https://github.com/ppetr/freer
An implementation of "Freer Monads, More Extensible Effects"
https://github.com/ppetr/freer
Last synced: over 1 year ago
JSON representation
An implementation of "Freer Monads, More Extensible Effects"
- Host: GitHub
- URL: https://github.com/ppetr/freer
- Owner: ppetr
- License: bsd-3-clause
- Created: 2016-01-02T09:22:05.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2016-01-02T09:22:43.000Z (over 10 years ago)
- Last Synced: 2025-01-31T08:44:26.075Z (over 1 year ago)
- Language: Haskell
- Size: 48.8 KB
- Stars: 4
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: changelog.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Freer: Extensible Effects with Freer Monads
Freer is an implementation of
["Freer Monads, More Extensible Effects"](http://okmij.org/ftp/Haskell/extensible/more.pdf). Much
of the implementation is a repackaging and cleaning up of the
reference materials provided
[here](http://okmij.org/ftp/Haskell/extensible/).
# Features
The key features of Freer are:
* An efficient effect system for Haskell as a library
* Implementations for several common Haskell monad instances:
* Reader
* Writer
* State
* StateRW: State in terms of Reader/Writer
* Trace
* Exception
* Core components for defining your own Effects
# Example: Teletype DSL
Here's what using Freer looks like:
```haskell
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module Teletype where
import Control.Monad.Freer
import Control.Monad.Freer.Internal
import System.Exit hiding (ExitSuccess)
--------------------------------------------------------------------------------
-- Effect Model --
--------------------------------------------------------------------------------
data Teletype s where
PutStrLn :: String -> Teletype ()
GetLine :: Teletype String
ExitSuccess :: Teletype ()
putStrLn' :: Member Teletype r => String -> Eff r ()
putStrLn' = send . PutStrLn
getLine' :: Member Teletype r => Eff r String
getLine' = send GetLine
exitSuccess' :: Member Teletype r => Eff r ()
exitSuccess' = send ExitSuccess
--------------------------------------------------------------------------------
-- Effectful Interpreter --
--------------------------------------------------------------------------------
runTeletype :: Eff '[Teletype] w -> IO w
runTeletype (Val x) = return x
runTeletype (E u q) = case decomp u of
Right (PutStrLn msg) -> putStrLn msg >> runTeletype (qApp q ())
Right GetLine -> getLine >>= \s -> runTeletype (qApp q s)
Right ExitSuccess -> exitSuccess
Left _ -> error "This cannot happen"
--------------------------------------------------------------------------------
-- Pure Interpreter --
--------------------------------------------------------------------------------
runTeletypePure :: [String] -> Eff '[Teletype] w -> [String]
runTeletypePure inputs req = reverse (go inputs req [])
where go :: [String] -> Eff '[Teletype] w -> [String] -> [String]
go _ (Val _) acc = acc
go [] _ acc = acc
go (x:xs) (E u q) acc = case decomp u of
Right (PutStrLn msg) -> go (x:xs) (qApp q ()) (msg:acc)
Right GetLine -> go xs (qApp q x) acc
Right ExitSuccess -> go xs (Val ()) acc
Left _ -> go xs (Val ()) acc
```
# Contributing
Contributions are welcome! Documentation, examples, code, and
feedback - they all help.
Be sure to review the included code of conduct. This project adheres
to the [Contributor's Covenant](http://contributor-covenant.org/). By
participating in this project you agree to abide by its terms.
## Developer Setup
The easiest way to start contributing is to install
[stack](https://github.com/commercialhaskell/stack). stack can install
GHC/Haskell for you, and automates common developer tasks.
The key commands are:
* stack setup : install GHC
* stack build
* stack clean
* stack haddock : builds documentation
* stack test
* stack bench
* stack ghci : start a REPL instance
# Licensing
This project is distrubted under a BSD3 license. See the included
LICENSE file for more details.
# Acknowledgements
This package would not be possible without the paper and the reference
implementation. In particular:
* Data.Open.Union maps to [OpenUnion41.hs](http://okmij.org/ftp/Haskell/extensible/OpenUnion41.hs)
* Data.FTCQueue maps to [FTCQueue1](http://okmij.org/ftp/Haskell/extensible/FTCQueue1.hs)
* Control.Monad.Freer* maps to [Union1.hs](http://okmij.org/ftp/Haskell/extensible/Eff1.hs)
There will be deviations from the source.