
Ertugrul Soeylemez
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
Kyle Murphy
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@haskell.org http://www.haskell.org/mailman/listinfo/beginners