sanctuary-js / sanctuary

:see_no_evil: Refuge from unsafe JavaScript
https://sanctuary.js.org
MIT License
3.04k stars 94 forks source link

Question: Purpose of Combinators? #529

Closed ghost closed 6 years ago

ghost commented 6 years ago

I just can't seem to grok the purpose of any of the combinators. For example, if I already have a value of "foo" why would I ever call S.I('foo') just to get it back? The same goes for the K, A, and T combinators. What purpose do they serve?

Is there already a write up somewhere I can't find, or can someone explain this?

Thanks!

Dave

davidchambers commented 6 years ago

Combinators are often useful as arguments to higher-order functions. We may wish, for example, to remove one level of nesting from a structure. S.chain (S.I) does exactly this:

> S.chain (S.I) ([[1, 2], [3, 4], [5, 6]])
[1, 2, 3, 4, 5, 6]

> S.chain (S.I) (S.Just (S.Just ('foo')))
Just ('foo')

Say we want to define isNothing and isJust in terms of S.maybe. We could write:

//    isNothing :: Maybe a -> Boolean
const isNothing = S.maybe (true) (_ => false);

//    isJust :: Maybe a -> Boolean
const isJust = S.maybe (false) (_ => true);

Note that we don't care about the value of _, so we could replace the lambdas:

//    isNothing :: Maybe a -> Boolean
const isNothing = S.maybe (true) (S.K (false));

//    isJust :: Maybe a -> Boolean
const isJust = S.maybe (false) (S.K (true));

These simple functions are not merely academic. :)

ghost commented 6 years ago

Thanks, @davidchambers . That helps a little. Still trying to wrap my head around all of this. I think I need a "for dummies:" guide. :-(

davidchambers commented 6 years ago

You needn't go out of your way to use these functions, but if you find yourself writing f (x => x) you might decide to use S.I instead.

ghost commented 6 years ago

AHA! Now I get it (or at least S.I) :-) Thanks.