Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created August 24, 2011 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snoyberg/1168128 to your computer and use it in GitHub Desktop.
Save snoyberg/1168128 to your computer and use it in GitHub Desktop.
Lift the inner monad for an enumerator
import Control.Monad.Trans.Error
import Control.Monad.Trans.Class
import Data.Enumerator
data In = In
data Out = Out
data OcrError = OcrError
instance Error OcrError
liftEnum :: Enumerator In IO (Either OcrError Out)
-> Enumerator In (ErrorT OcrError IO) Out
liftEnum enum step = unpeel $ enum $ peel step
peel :: Step In (ErrorT e IO) Out -> Step In IO (Either e Out)
peel (Yield b s) = Yield (Right b) s
peel (Error e) = Error e
peel (Continue k) = Continue $ \s -> Iteratee $ do
x <- runErrorT $ runIteratee $ k s
case x of
Left e -> return $ Yield (Left e) EOF
Right x -> return $ peel x
unpeel :: Iteratee In IO (Either OcrError Out)
-> Iteratee In (ErrorT OcrError IO) Out
unpeel (Iteratee mstep) = Iteratee $ do
step <- lift mstep
unpeel' step
unpeel' :: Step In IO (Either OcrError Out)
-> ErrorT OcrError IO (Step In (ErrorT OcrError IO) Out)
unpeel' (Yield (Left e) _) = ErrorT $ return $ Left e
unpeel' (Yield (Right b) s) = ErrorT $ return $ Right $ Yield b s
unpeel' (Error e) = return $ Error e
unpeel' (Continue k) = ErrorT $ return $ Right $ Continue $ \s -> Iteratee $ do
step <- lift $ runIteratee $ k s
unpeel' step
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment