Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 22:17
    CrossEye commented #2779
  • Jan 31 2019 21:04
    ArturAralin commented #2779
  • Jan 31 2019 20:08
    CrossEye commented #2779
  • Jan 31 2019 18:56
    buzzdecafe commented #2631
  • Jan 31 2019 18:09
    ArturAralin commented #2779
  • Jan 31 2019 16:18
    CrossEye commented #2779
  • Jan 31 2019 16:10
    CrossEye commented #2631
  • Jan 31 2019 16:06
    CrossEye commented #2777
  • Jan 31 2019 14:44
    ArturAralin opened #2779
  • Jan 31 2019 07:39
    inferusvv commented #2631
  • Jan 31 2019 03:07
    sespinozj commented #2771
  • Jan 31 2019 02:33
    machad0 commented #2771
  • Jan 31 2019 02:26
    JeffreyChan commented #2777
  • Jan 30 2019 14:30
    CrossEye closed #2777
  • Jan 30 2019 12:13
    vanyadymousky updated the wiki
  • Jan 30 2019 01:42
    JeffreyChan commented #2777
  • Jan 29 2019 21:06
    vanyadymousky updated the wiki
  • Jan 29 2019 16:28
    CrossEye commented #2777
  • Jan 29 2019 15:50
    mbostock commented #2772
  • Jan 29 2019 15:48
    CrossEye commented #2772
Tobias Pflug
@gilligan
sure, plenty ;}
Tobias Pflug
@gilligan
hm, i cam agonising about how this could be written in a more efficiently : https://gist.github.com/gilligan/dc1409dee420798c73dc ( @Avaq you see i extracted that one function from there). I have modify keys and values of an object and currently this happens in two successive traversals which I already don't like but don't see right now how to avoid this. Any ideas anyone ? ;-)
Aldwin Vlasblom
@Avaq
I did a small review sweep of the code; http://goo.gl/uyFGIF, didn't really solve the two-traversals thing, it's difficult since one traversal is recursive and the other isn't. But my comments might be helpful.
Off to bed now, see you.
Tobias Pflug
@gilligan
@Avaq thanks!
Aldwin Vlasblom
@Avaq
I want to learn about type transformers, like ReaderT. Can somebody give me a brief explanation, example or resource so I can get started? What is their purpose? Is there a benefit to using a ReaderTFuture over a Reader[Future]? I played a bit and can achieve the same with both (though the ReaderT is more convenient): http://goo.gl/J2J9lS. Am I even using it right? Is it merely a convenience?
Scott Sauyet
@CrossEye
Sorry, Avaq, still haven't spent any time with them.

Thinking about #1543, I became puzzled by something, and I was wondering if anyone has any insight:

Because it's easy to work with, many of our examples of lift use add, so me might define mAdd = lift(add). Well add is a straightforward function, and it happens to be commutative, add(a, b) ≡ add(b, a). It simply seemed obvious that mAdd would also be commutative. In simple cases, it is:

mAdd(Maybe.Just(10), Maybe.Just(32)); //=> Maybe.Just(42)
mAdd(Maybe.Just(32), Maybe.Just(10)); //=> Maybe.Just(42)

But it's definitely not:

R.lift(R.add)(Either.Right(10), Either.Left('oops')); //=> Either.Left('oops')
R.lift(R.add)(Either.Left('oops'), Either.Right(10)); //=> Either.Right(10)

My question is: Is my intuition leading me astray? Or should we expect that if fn is commutative, then lift(fn) is also commutative? If so, is there something wrong with lift or one of its dependencies? Or is there something the matter with Either?


Never mind. It clearly cannot be commutative:

R.lift(R.add)(Either.Left('oops'), Either.Left('a-daisy'));

So my intuition is off.

Tobias Pflug
@gilligan
@Avaq "type transformer" ? Well you mean monad transformer right?
Aldwin Vlasblom
@Avaq
Yeah
Is it only doable with Monads though?
Why not all Functors?
Wasn't certain about that either, so I said "type" to stay generic. :)
Aldwin Vlasblom
@Avaq
But now, knowing that it's just for Monads, I find more info on the internet :)
Still not sure where I'd use them though. :\
Tobias Pflug
@gilligan
I can prolly give you some links later
For use with JS? I would not care
For Haskell: certainly
Aldwin Vlasblom
@Avaq
Haha, I see. I only just started with FP a few months ago in JS, so I wouldn't know. :)
Tobias Pflug
@gilligan
If you want to do IO but also be able to- say encode errors with Either or Maybe you want to reach for a transformer so you can stack those monads
Haskell tho
Aldwin Vlasblom
@Avaq
Cool, thanks @gilligan, I'm sure I'll find my way around the Haskell examples.
Hardy Jones
@joneshf
@CrossEye Assuming lift doesn't do any kind of reflection or something, that Either you're using looks broken.
@CrossEye that is to say, it only uses ap, map and friends.
@Avaq it's only necessary with Monads, well more accurately it's only necessary with Chains. Really they should be called Chain Transformers, or Bind Transformers, or whatever the language uses.
but since not all languages/libraries distinguish between Monad and Chain/Bind, they have the name they have.
@Avaq the reason they are necessary is that the composition of two Chains is not necessarily another Chain.
If you take any two Functors, and compose them, the result is always a Functor.
same with Applys, and Applicatives.
Hardy Jones
@joneshf
What this means is that you could create a Composition data type that encoded this logic. Give it two composable data types, and you get Functor, Apply, Applicative behavior for free.
Tobias Pflug
@gilligan
Functor Composition would be a natural Transformation - right?
@joneshf actually- which langs /do/ differentiate between Monad/Chain ? Fantasyspec was the first time I saw that distinction
Hardy Jones
@joneshf
// We can compose any two `Functor`s `x` and `y`
const Comp = x => ({
  map: f => x.map(y => y.map(f)),
  toString: () => x.map(y => y.toString()).toString(),
});

const None = {
  map: _ => None,
  toString: () => 'None',
};

const Some = x => ({
  map: f => Some(f(x)),
  toString: () => `Some(${x})`,
});

const Left = x => ({
  map: _ => Left(x),
  toString: () => `Left(${x})`,
});

const Right = x => ({
  map: f => Right(f(x)),
  toString: () => `Right(${x})`,
});

const someRight = Comp(Some(Right(3)));
console.log(`${someRight.map(x => x + 1)}`); //=> Some(Right(4))

const someLeft = Comp(Some(Left(3)));
console.log(`${someLeft.map(x => x + 1)}`); //=> Some(Left(3))

const noneRight = Comp(None);
console.log(`${noneRight.map(x => x + 1)}`); //=> None
quick example.
so you only have to map once, rather than going down in there multiple times.
And if you have 3, 4, 5, etc types you're composing, well, you just keep on Composing.
and still you only map once.
It extends to ap and of as well.
But chain doesn't work.
so you need an explicit way to chain two data types.
Actually, I'm not sure if all data types can have a transformer version.
Hardy Jones
@joneshf
@gilligan purescript, scalaz, there are libs in hackage as well.
well, languages and libraries.
fantasy-land as you pointed out.
Extending the example above:

const Id = x => ({
  map: f => Id(f(x)),
  toString: () => `Id(${x})`,
});

const nested = Comp(Some(Comp(Id(Comp(Right(Comp(Some(Some(3)))))))));
console.log(`${nested.map(x => x + 1)}`); //=> Some(Id(Right(Some(Some(4)))))
Of course, you probably want to toString to tell you it's a Comp at each level.
Hardy Jones
@joneshf
but it's just a quick example :)
The creation is pretty ugly right there, but since Applicatives compose, you could factor all that out similar to how ramda does compose/pipe. and just use of a whole bunch of times.