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.
Monads be escaped from?
Yes. This is very easy with many
Monads, such as
Identity, and more. One of the most common
Monads that is escaped from is the function
(->) r. If it weren't possible to turn a function into a value, then Haskell wouldn't have much going for it.
IObe 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
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.
It varies from
Monad, but most monad transformers have
> :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
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.