2

This excellent answer in this question demonstrates how bind can be written in terms of join and fmap:

(>>=) :: m v -> (v -> m w) -> m w

says "if you have a strategy to produce a v, and for each v a follow-on strategy to produce a w, then you have a strategy to produce a w". How can we capture that in terms of join?

mv >>= v2mw = join (fmap v2mw mv)

But, I don't understand how v2mw, which has a type of a -> m b type checks to the first argument of fmap.

fmap :: Functor f => (a -> b) -> f a -> f b

Community
  • 1
  • 1
Kevin Meredith
  • 38,251
  • 58
  • 190
  • 340

1 Answers1

10

Let's say v2mw :: c -> m d, just so things aren't ambiguous, and

fmap :: Functor f => (a -> b) -> f a -> f b

Then fmap v2mw works out so that f ~ m, a ~ c and b ~ m d, so

fmap v2mw :: m c -> m (m d)

and join :: m (m e) -> m e, so join (fmap v2mw mv) has type m d as expected.

Louis Wasserman
  • 172,699
  • 23
  • 307
  • 375