bench | ||
examples/src | ||
src | ||
tests | ||
.gitignore | ||
.travis.yml | ||
CHANGELOG.md | ||
CODE_OF_CONDUCT.md | ||
LICENSE | ||
package.yaml | ||
README.md | ||
Setup.hs | ||
stack.yaml |
Freer: Extensible Effects with Freer Monads
Description
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.
Features
The key features of freer-simple
are:
- An efficient effect system for Haskell as a library.
- Implementations for several common Haskell monads as effects:
Reader
Writer
State
Trace
Error
- Core components for defining your own Effects.
Example: Console DSL
Here's what using freer-simple
looks like:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module Console where
import Control.Monad.Freer
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 ()
Contributing
Contributions are welcome! Documentation, examples, code, and feedback - they all help.
Developer Setup
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 clean
stack haddock
— builds documentation
More information about stack
can be found in its documentation.
Licensing
This project is distributed under a BSD3 license. See the included LICENSE file for more details.
Acknowledgements
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.OpenUnion
maps to OpenUnion51.hsData.FTCQueue
maps to FTCQueue1Control.Monad.Freer*
maps to Eff1.hs
There will be deviations from the source.