[Haskell-beginners] fmap versus bind
Daniel Fischer
daniel.is.fischer at googlemail.com
Tue May 3 18:00:40 CEST 2011
On Tuesday 03 May 2011 17:32:14, Patrick LeBoutillier wrote:
> Hi all,
>
> On Mon, May 2, 2011 at 9:56 PM, Sean Perry <shaleh at speakeasy.net> wrote:
> > i came across hlint today and ran it on my experiments. It pointed out
> > places where I was overly cautious with parens or used a $ and forget
> > to remove it later. But one suggestion it made I was curious about.
> >
> > Why does it recommend using fmap over >>=? Idiomatically does fmap
> > make more sense when the Monad is more like a collection?
> >
> > For instance I had "(applyOp op x y) >>= (flip (:) ds)". This seems
> > more clear than "fmap ((:) ds) (applyOp op x y)".
>
> I'm trying to understand this example and I can't get the types to line
Right, they don't match.
As first argument of (>>=), we must have
applyOp op x y :: m a, where m is some monad.
flip (:) ds = (: ds) = \x -> x:ds :: a -> [a], where ds :: [a].
So m = [],
applyOp op x y :: [a]
applyOp op x y >>= flip (:) ds :: [a]
On the other hand, assuming the flip has just been forgotten while typing,
fmap :: (a -> b) -> [a] -> [b] (using the specific Functor of this
example), the fmapped function has type (a -> [a]), so
fmap (flip (:) ds) (applyOp op x y) :: [[a]]
There's a concat missing here, or a return in the (>>=) piece to make the
types fit.
If the omission of flip in the fmap is not accidental, there's more amiss.
> up. Can you provide the "real" types for ds and (applyOp op x y)?
>
> This is what I'm working out:
>
> fmap ((:) ds) (applyOp op x y)
> == fmap (ds :) (applyOp op x y)
> == fmap (\dss -> ds : dss) (applyOp op x y)
>
> (applyOp op x y) >>= (flip (:) ds)
> == (applyOp op x y) >>= (: ds)
> == (applyOp op x y) >>= (\d -> d : ds)
>
>
> To my untrained eyes is doesn't even look like the code is doing the
> same thing...
> What am I missing here (or more probably where is my mistake)?
>
>
> Patrick
More information about the Beginners
mailing list