
On Tuesday 03 May 2011 17:32:14, Patrick LeBoutillier wrote:
Hi all,
On Mon, May 2, 2011 at 9:56 PM, Sean Perry
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