<div dir="ltr"><div>many thanks! I will take a look at it.<br><br></div>cheers and thanks to all :-)<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 15, 2015 at 10:28 PM, Christopher Allen <span dir="ltr"><<a href="mailto:cma@bitemyapp.com" target="_blank">cma@bitemyapp.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">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.<div><br></div><div>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`.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Want to see what I mean?</div><div><br></div><div>Play with some code that uses <a href="https://hackage.haskell.org/package/time-1.3/docs/Data-Time-Clock.html#v:getCurrentTime" target="_blank">https://hackage.haskell.org/package/time-1.3/docs/Data-Time-Clock.html#v:getCurrentTime</a> 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.</div><div><br></div><div>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.</div><div><br></div><div>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: <a href="https://github.com/bitemyapp/learnhaskell" target="_blank">https://github.com/bitemyapp/learnhaskell</a></div><div><br></div><div>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.</div><div><br></div><div>--- Chris Allen</div><div><br></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 15, 2015 at 3:12 PM, Julian Birch <span dir="ltr"><<a href="mailto:julian.birch@gmail.com" target="_blank">julian.birch@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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 S<span></span>tring. And through Monad, you can turn IO (IO String) back to IO String.<div><br></div><div>Hope this helps.<div><div><br><br>On Thursday, January 15, 2015, Marcin Mrotek <<a href="mailto:marcin.jan.mrotek@gmail.com" target="_blank">marcin.jan.mrotek@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
A list ([]) is also a monad, and a String is defined as a list of<br>
characters ([Char]). So in your example, it's as if you were trying to<br>
use (>>=) operator on two different monads ([] and IO), which is<br>
impossible. To make a pure value a monadic value, you need to use<br>
return:<br>
<br>
g = readLn >>= (\a -> return (f a))<br>
<br>
which is equivalent to composing f with return:<br>
<br>
g = readLn >>= return.f<br>
<br>
Regards,<br>
Marcin<br>
_______________________________________________<br>
Beginners mailing list<br>
<a>Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</blockquote></div></div></div><br><div><div><br>-- <br>Sent from an iPhone, please excuse brevity and typos.<br>
</div></div><br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>