[Haskell-beginners] help with IO guards

Christopher Allen cma at bitemyapp.com
Thu Jan 15 21:28:55 UTC 2015

I haven't seen anybody explain the real reasons you can't yank `a` out of
something of type `IO a`, so I thought I'd attempt to clear a few things up.

It's true that you cannot *in general* extract a value of type `a` from
something of type `Monad m => m a` but those reasons are *not* why you
can't in the case of IO. You can't with Monad in general because the
typeclass doesn't provide a method with the type `m a -> a`, in fact, it
only provides the opposite: `a -> m a`.

The real reason you can't pattern match on or otherwise extract values from
IO is that it's an abstract datatype - on purpose. The constructor is not
exported, the internals are hidden.

You are using a non-strict programming language. The IO datatype is how the
implementation knows not to replace the thunk with its value when evaluated.

Want to see what I mean?

Play with some code that uses
to get the current time. Note how each time you force evaluation of the `IO
UTCTime` you're getting a new UTCTime each time. Then wrap it in
`unsafePerformIO` - it'll only get executed once. This is *definitely* not
the semantics you want, you're too new to know when you'd want the unsafe*
functions for now.

If you aren't comfortable with monads, no amount of thrashing is going to
let you avoid using Functor/Applicative/Monad if you want to interact with
values produced in IO.

I wrote a guide for learning Haskell, it covers Functor/Applicative/Monad
which are *everywhere* - not just for use with IO. This is the guide:

There are people used to teaching and assisting with the courses
recommended in my guide (cis194 & NICTA course) on Freenode IRC at
#haskell-beginners. There are tons of people equipped to help you in
#haskell as well.

--- Chris Allen

On Thu, Jan 15, 2015 at 3:12 PM, Julian Birch <julian.birch at gmail.com>

> Going back to an earlier question: a monad is a bit like a roach motel.
> You can check in but you can't leave. (This isn't true of every Monad, but
> the point is there's no guarantees.) In particular, you can't go from IO
> String to String _at all_. But you can, through Functor, pass it to a
> function that takes a plain String. And through Monad, you can turn IO
> (IO String) back to IO String.
> Hope this helps.
> On Thursday, January 15, 2015, Marcin Mrotek <marcin.jan.mrotek at gmail.com>
> wrote:
>> Hello,
>> A list ([]) is also a monad, and a String is defined as a list of
>> characters ([Char]). So in your example, it's as if you were trying to
>> use (>>=) operator on two different monads ([] and IO), which is
>> impossible. To make a pure value a monadic value, you need to use
>> return:
>> g = readLn >>= (\a -> return (f a))
>> which is equivalent to composing f with return:
>> g = readLn >>= return.f
>> Regards,
>> Marcin
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
> --
> Sent from an iPhone, please excuse brevity and typos.
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20150115/75061d30/attachment.html>

More information about the Beginners mailing list