The freer-simple library (a fork of freer-effects) is an implementation of an effect system for Haskell, which is based on the work of Oleg Kiselyov et al.:
Much of the implementation is a repackaging and cleaning up of the reference materials provided here.
The key features of freer-simple are:
- An efficient effect system for Haskell as a library.
- Implementations for several common Haskell monads as effects:
ReaderWriterStateTraceError
- Core components for defining your own Effects.
Here's what using freer-simple looks like:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
module Console where
import Control.Monad.Freer
import Control.Monad.Freer.Error
import Control.Monad.Freer.State
import Control.Monad.Freer.Writer
import System.Exit hiding (ExitCode(ExitSuccess))
--------------------------------------------------------------------------------
-- Effect Model --
--------------------------------------------------------------------------------
data Console r where
PutStrLn :: String -> Console ()
GetLine :: Console String
ExitSuccess :: Console ()
putStrLn' :: Member Console effs => String -> Eff effs ()
putStrLn' = send . PutStrLn
getLine' :: Member Console effs => Eff effs String
getLine' = send GetLine
exitSuccess' :: Member Console effs => Eff effs ()
exitSuccess' = send ExitSuccess
--------------------------------------------------------------------------------
-- Effectful Interpreter --
--------------------------------------------------------------------------------
runConsole :: Eff '[Console, IO] a -> IO a
runConsole = runM . interpretM (\case
PutStrLn msg -> putStrLn msg
GetLine -> getLine
ExitSuccess -> exitSuccess)
--------------------------------------------------------------------------------
-- Pure Interpreter --
--------------------------------------------------------------------------------
runConsolePure :: [String] -> Eff '[Console] w -> [String]
runConsolePure inputs req = snd . fst $
run (runWriter (runState inputs (runError (reinterpret3 go req))))
where
go :: Console v -> Eff '[Error (), State [String], Writer [String]] v
go (PutStrLn msg) = tell [msg]
go GetLine = get >>= \case
[] -> error "not enough lines"
(x:xs) -> put xs >> pure x
go ExitSuccess = throwError ()Contributions are welcome! Documentation, examples, code, and feedback - they all help.
The easiest way to start contributing is to install stack. Stack can install GHC/Haskell for you, and automates common developer tasks.
The key commands are:
stack setup— install required version of GHC compilerstack build— builds project, dependencies are automatically resolvedstack test— builds project, its tests, and executes the testsstack bench— builds project, its benchmarks, and executes the benchamksstack ghci— start a REPL instance with a project modules loadedstack cleanstack haddock— builds documentation
More information about stack can be found in its documentation.
This project is distributed under a BSD3 license. See the included LICENSE file for more details.
The freer-simple package started as a fork of freer-effects by Ixperta Solutions, which in turn is a fork of freer by Allele Dev. All implementations are based on the paper and reference implementation by Oleg Kiselyov. In particular:
Data.OpenUnionmaps to OpenUnion51.hsData.FTCQueuemaps to FTCQueue1Control.Monad.Freer*maps to Eff1.hs
There will be deviations from the source.