{-# LANGUAGE TemplateHaskell #-}

module MonadLab.ListIo (
   listIoMonad
 ) where

import Prelude hiding (Monad)
import Language.Haskell.TH
import MonadLab.CommonTypes

listIoMonad :: Monad
listIoMonad = (listIoTypeCon , listIoReturn , listIoBind, [(List, [merge]), (Io, [liftIO])], listIoBaseLift)

listIoTypeCon :: MonadTypeCon
listIoTypeCon = \t -> appT listT (appT (conT ''IO) t) 

listIoReturn :: ReturnExpQ
listIoReturn = [| \v -> [return v] |]

listIoBind :: BindExpQ
listIoBind = [| \m -> \f -> concatMap (>>= f) m |]

liftIO :: NonProperMorphismExpQ
liftIO = [| \io -> [io] |]

merge :: NonProperMorphismExpQ
merge = [| concat |]

listIoBaseLift :: LiftExpQ
listIoBaseLift = [| map return |]