I don't understand why I can't decompose a (let's say IO) monad. Like IO a -> a
?
My question originated when using happstack and wanting to get the Text
out of ServerPart (Maybe Text)
which is returned by (optional $ lookText "domain")
.
Then I remembered reading that IO
monad can't be escaped.
I've read about unsafePerformIO
and the reasons why it is bad, but none of those reasons seem to answer my question.
Monad
s be escaped from?Yes. This is very easy with many Monad
s, such as Maybe
, Either a
, State s
, Identity
, and more. One of the most common Monad
s that is escaped from is the function Monad
: (->) r
. If it weren't possible to turn a function into a value, then Haskell wouldn't have much going for it.
IO
be escaped from?Unfortunately, yes. It would be a lot better for beginners if they didn't google around and see that they can technically escape from IO
using unsafePerformIO
, which as you might have guessed is not safe. It is not meant to be used in normal code, but is rather a backdoor into the runtime system for when you really need it. Primarily, it's used for implementing some lower level libraries like Vector
, but also for interfacing with external shared libraries (DLLs). If you're not writing that kind of code, don't use unsafePerformIO
. Otherwise, you will end up with code that becomes difficult to reason about and maintain because it bypasses the type system.
Monad
s?It varies from Monad
to Monad
, but most monad transformers have run-
, eval-
or exec-
methods:
> :m Control.Monad.State
> runState (modify (*10) >> get >>= return . show) 1
("10", 10)
> :type runState (modify (*10) >> get >>= return . show) 1
runState (modify (*10) >> get >>= return . show) 1 :: (String, Int)
> evalState (modify (*10) >> get >>= return . show) 1
"10"
> execState (modify (*10) >> get >>= return . show) 1
10
The Maybe
Monad
has several ways to escape from it:
> :m Data.Maybe
> maybe "nada" show (Just 2)
"2"
> maybe "nada" show Nothing
"nada"
> fromMaybe 1 (Just 10)
10
> fromMaybe 1 Nothing
1
> fromJust (Just 1)
1
> fromJust Nothing
*** Exception: Maybe.fromJust: Nothing
So as you can see, not all of them are safe to use either.
I don't know, I haven't used Happstack enough to know about it. However, a quick search led me to this example on their website, which looks pretty applicable to your situation.