
On 12/7/06, Cat Dancer
On 12/7/06, apfelmus@quantentunnel.de
wrote: I'm sure from a single example I could understand what was going on and elaborate from there. Let's say I want to get a line from the user, and either return an integer or an error string using ErrorT.
import Control.Monad.Error import Control.Monad.Trans
foo :: ??
foo :: ErrorT String IO Int if you're going to use this very often, you can use a line like type M = ErrorT String IO and then foo :: M Int
foo = do -- something like this? a <- getLine
Since ErrorT String IO Int is not the same as IO, you can't use IO operations directly. In this case, you want: < a <- lift getLine
if length a == 1 then return 123 else throwError "not a single character"
This is all fine
main = do r <- ?? foo ??
You want: < r <- runErrorT foo and then this will behave as expected:
print r -- prints Left "not a single character" or Right 123 ?
Your foo operation is in a monad which wraps IO. lift allows IO operations inside that wrapper, and runErrorT removes the wrapper. The same basic pattern works for other wrappers (like StateT or ListT) or combinations of wrappers (like StateT Int (ErrorT String IO)) /g -- It is myself I have never met, whose face is pasted on the underside of my mind.