module System.IO.Lazy.Applicative where
import qualified Data.ApplicativeChain as Chain
import Control.Applicative (Applicative(pure, (<*>)), )
import Control.Monad (liftM2, )
import System.IO.Unsafe (unsafeInterleaveIO, )
newtype T a = Cons {decons :: IO (Chain.T a)}
data RunAll = RunAll
deriving Show
instance Functor T where
fmap f = Cons . fmap (fmap f) . decons
instance Applicative T where
pure = Cons . return . Chain.Cons Chain.RunAll
Cons f <*> Cons x = Cons $ liftM2 (<*>) f x
liftIO :: IO a -> T a
liftIO = Cons . unsafeInterleaveIO . fmap (Chain.Cons Chain.RunAll)
run :: T a -> IO a
run = fmap Chain.result . decons