Skip to content

Instantly share code, notes, and snippets.

@jhewlett
Created April 22, 2017 04:02
Show Gist options
  • Save jhewlett/24e79f7b42f490a5a566cf9dc80b39db to your computer and use it in GitHub Desktop.
Save jhewlett/24e79f7b42f490a5a566cf9dc80b39db to your computer and use it in GitHub Desktop.
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TemplateHaskell #-}

module Main where

import Control.Monad.Except (ExceptT)
import qualified Control.Monad.Except as Except
import Control.Monad.Free
import Control.Monad.Free.TH
import Control.Monad.IO.Class (liftIO)

data Console next
  = ReadLine (String -> next)
  | WriteLine String
              next
  | ThrowError String
  deriving (Functor)

makeFree ''Console

program :: Free Console ()
program = do
  l <- readLine
  throwError "Error"
  writeLine l

interpret' :: Console next -> ExceptT String IO next
interpret' (ReadLine n) = do
  l <- liftIO getLine
  pure $ n l
interpret' (WriteLine l n) = do
  liftIO $ putStrLn l
  pure n
interpret' (ThrowError e) = Except.throwError e

main = do
  r <- Except.runExceptT $ foldFree interpret' program
  print r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment