RE: [Haskell-cafe] The essence of my monad confusion

2009-05-27 Thread Paul Keir
Thanks for all the help. The simplified example indeed threw away too
much. There were no side effects.

Brent, of course I couldn't create your function; though I gained
through trying. I then found it useful to consider the type of:

fmap (\x - putStrLn x) getLine

which is IO (IO ()) and hence displays nothing to the screen.

Felipe, your recursive example was also compelling and concise.

Antoine, I see how the join capacity of a Monad can be useful in this
issue. I'm also reminded of what * can bring to fmap/$.

On reflection, I often trip up when learning by comparing IO to simpler
monads such as [] and Maybe. But [] and Maybe never have effects, and so
are poor foils. The ((-) t) monad is henceforth in my toolbox.

Paul


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The essence of my monad confusion

2009-05-02 Thread Antoine Latter
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


Re: [Haskell-cafe] The essence of my monad confusion

2009-05-02 Thread Brent Yorgey
On Sat, May 02, 2009 at 05:31:03PM +0100, Paul Keir 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 simplification does not preserve the crucial aspect of the
example: (putStrLn blah) has an effect (namely, printing something
on the screen), whereas (return blah) never has an effect (whatever
effect means for the particular monad in question).  You seem to be
confusing the return value of a monadic computation with its side
effects.  In the case of 'putStrLn blah', the return value is (),
and the side effect is to print blah to the screen; in the case of
'return blah', the return value is blah and there are no side
effects.

Since IO is a monad, we can compute the result of 'getLine' and then
use it to decide which of the two putStrLns to run; the effect of the
other one (printing something on the screen) will never happen.  But
there is no way to do this with only the Applicative interface.  Try
writing a function

  f :: IO String - IO () - IO () - IO ()

which has the same behavior as the 'do text - getLine...' example
above, using *only* the Applicative instance of IO; you won't be able
to do it.  Depending how you implement f, it may execute only the
first IO (), or only the second, or both, or neither; but it will
always be the same.  You won't be able to have f choose which to
execute based on the result of the IO String parameter.

-Brent
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The essence of my monad confusion

2009-05-02 Thread Felipe Lessa
On Sat, May 02, 2009 at 05:31:03PM +0100, Paul Keir wrote:
 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)

Then, how about

getMyLine = getLine = \text -
if null text then getMyLine else return m

Can you, using functors, decide to run 'getLine' again or not?

HTH,

--
Felipe.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe