[Haskell-beginners] Re: = vs <-

Kyle Murphy orclev at gmail.com
Sat Aug 14 01:53:48 EDT 2010


> Ertugrul Soeylemez <es at ertes.de> wrote:
> I think, this is very misleading.  You never get "out of a monad", you
> get "into" it, and you can do that whenever you want.  Remember that the
> monadic world is inside of the pure world, not the pure world inside of
> the monadic world.  In fact, the monadic world is part of it.

Not really, it depends on how you look at things. If you want to use
the result of something that returns an IO Monad inside of a pure
function, you really can't do that without in turn making that
function impure (that is, putting it inside of the IO Monad as well),
so to one way of looking at it, values (and functions) exist inside
Monads and with few exceptions are impossible to remove from those
Monads. You can always embed your pure function inside a non-pure
function, but the opposite is not true. Most of the monads do provide
functions like fromJust, and unsafePerformIO (never use this,
seriously) that can allow you to escape from the monad, but doing so
is often risky. The monadic world as you put it, really isn't inside
of the pure world except in theory. From a practical standpoint
everything exists inside the IO monad at some level, it's just lower
level functions that are pure (that is, functions can be pure, but at
some point they MUST be called from the IO monad). I know
theoretically monads are built on top of pure math, but to me the
difference between monads as a concept and monads as implemented in
Haskell, is similar to the difference between proving a program to be
correct, and actually running it.

> You are complicating things artifically.  For example there is no reason
> to have all those parentheses, because (>>=) is associative by
> definition.
>
> The do-notation doesn't make nasty things nice.  It makes nice things
> nicer.  Don't be afraid to use raw monadic combinators, because
> sometimes they are much better:

The example I provided was still relatively simple, and apparently
didn't need all the parentheses, but I wasn't going to bet on it, and
had I used other operators, say some provided by a module, who knows
what kinds of associativity would be involved. I generally always use
parentheses around lambdas if for no other reason than to make it
easier to see what their scope is.

I never said the monad operators were nasty, or that the do notation
was nicer, just that often it is more convenient. There are instances
where I find it simpler and easier to read an expression using the
monad operators rather than do notation, and vice versa, so it really
depends on the particular instance. Sometimes I even find it most
readable to combine the two into something like:

foobar = do
  baz <- foo 42
  bar baz >>= putStrLn . show . xyzzy baz

Once again, this is not supposed to be a specific example, just a
conceptual one vaguely representative of the form of actual ones I've
run across before.

-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.



On Fri, Aug 13, 2010 at 20:06, Ertugrul Soeylemez <es at ertes.de> wrote:
> Kyle Murphy <orclev at gmail.com> wrote:
>
>> Remember that in most cases, once something is "inside" of a monad (IO
>> in this case), it's very difficult, impossible, to get it out again.
>
> I think, this is very misleading.  You never get "out of a monad", you
> get "into" it, and you can do that whenever you want.  Remember that the
> monadic world is inside of the pure world, not the pure world inside of
> the monadic world.  In fact, the monadic world is part of it.
>
> The name bound by '<-' is something you can refer to in the pure world.
> There is nothing difficult about using the result of a monadic
> computation in the pure world.  Just give it a name and refer to it, and
> that's it.
>
>
>> The do syntax just adds a convenient abstraction so that you don't
>> have to construct complex chains of >>= and >> operations by hand. In
>> our limited example this is fairly trivial, but consider something
>> like:
>>
>> main = do
>>   something <- foo
>>   blah <- bar something
>>   moreblah <- baz something blah
>>   putStrLn moreblah
>>   putStrLn "really long chain now"
>
> Pretty straightforward:
>
>  main =
>    foo >>= \something ->
>    bar something >>= \blah ->
>    baz something blah >>= \moreblah ->
>    putStrLn moreblah >>
>    putStrLn "really long chain now"
>
>
>> which would be translated to:
>>
>> main = foo >>= (\something -> bar something >>= (\blah -> baz
>> something blah >>= (\moreblah -> putStrLn moreblah >> (putStrLn
>> "really long chain now"))))
>
> You could just as well write:
>
>  main = do { something <- foo; blah <- bar something;
>    moreblah <- baz something blah; putStrLn moreblah; putStrLn
>    "really long chain now" }
>
> You are complicating things artifically.  For example there is no reason
> to have all those parentheses, because (>>=) is associative by
> definition.
>
> The do-notation doesn't make nasty things nice.  It makes nice things
> nicer.  Don't be afraid to use raw monadic combinators, because
> sometimes they are much better:
>
>  main = getArgs >>= mapM_ (readFile >=> putStr)
>
> Much more concise than:
>
>  main = do
>    files <- getArgs
>    forM_ files $ \file -> do
>      content <- readFile file
>      putStr content
>
>
> Greets,
> Ertugrul
>
>
> --
> nightmare = unsafePerformIO (getWrongWife >>= sex)
> http://ertes.de/
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>


More information about the Beginners mailing list