{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Trans.Writer (WriterT, runWriterT)
import Control.Monad.Writer.Lazy (MonadWriter(..), tell)
import Control.Monad.IO.Class (MonadIO, liftIO)
newtype App a b = App { unApp :: WriterT a IO b } deriving (Functor, Applicative, Monad, MonadWriter a, MonadIO)
runApp :: App a b -> IO (b, a)
runApp = runWriterT . unApp
app :: App [String] Int
app = do
tell ["A"]
content <- liftIO $ readFile "./main.hs"
tell ["B"]
return (length content)
main = do
res <- runApp app
print res