On Sat, May 2, 2009 at 11:31 AM, Paul Keir <pk...@dcs.gla.ac.uk> wrote: > On the wiki page for Applicative Functors > (http://www.haskell.org/haskellwiki/Applicative_functor) a familiar > characteristic of monads is quoted; that they "allow you to run actions > depending on the outcomes of earlier actions". I feel comfortable with > Functors and Applicative Functors, but I don't yet get that "extra power" > that monads provide. > > An example immediately follows that quotation on the wiki: > > do text <- getLine > if null text > then putStrLn "You refuse to enter something?" > else putStrLn ("You entered " ++ text) > > For simplicity's sake, I modified it to avoid using the IO monad; the "text" > binding is now provided by the first parameter, and (=<<) is used due to its > similarity to fmap: > > bar :: Monad m => m String -> m String > bar as = (=<<) (\a -> if null a then return "nothing" else return > "something") as > > This works fine, so bar ["Blah"] gives ["something"], and bar (Just "") > gives ["nothing"]. > > But, I can get the same effect using a Functor (replacing (=<<) with fmap): > > bar2 :: Functor f => f String -> f String > bar2 as = fmap (\a -> if null a then "nothing" else "something") as > > Can anyone help me out of the swamp? >
Suppose I had functions: bar3 :: Functor f => String -> f Bool bar4 :: Funcotr f => Bool -> f Integer If the only thing I have is the functor constraint, to chain them together I have to end up with something of type (Functor f => String -> f (f Integer)). If I had a Monad constraint on bar3 and bar4 I could flatten the result type and get rid of the "double nesting" and end up with a function of type (String -> f Integer). So it's not about what a single function can do, but what tools I have to compose the functions. Antoine _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe