Closed ghost closed 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. :)
Thanks, @davidchambers . That helps a little. Still trying to wrap my head around all of this. I think I need a "for dummies:" guide. :-(
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.
AHA! Now I get it (or at least S.I
) :-) Thanks.
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 theK
,A
, andT
combinators. What purpose do they serve?Is there already a write up somewhere I can't find, or can someone explain this?
Thanks!
Dave