joshvera/effects
{ "createdAt": "2016-08-09T15:57:56Z", "defaultBranch": "master", "description": "An implementation of \"Freer Monads, More Extensible Effects\".", "fullName": "joshvera/effects", "homepage": null, "language": "Haskell", "name": "effects", "pushedAt": "2018-10-17T20:33:55Z", "stargazersCount": 20, "topics": [], "updatedAt": "2022-07-25T04:39:46Z", "url": "https://github.com/joshvera/effects"}Effects: Extensible Effects with Freer Monads
Section titled “Effects: Extensible Effects with Freer Monads”Effects is an implementation of “Freer Monads, More Extensible Effects”. Much of the implementation is a repackaging and cleaning up of the reference materials provided here.
Features
Section titled “Features”The key features of Effects 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
Section titled “Example: Teletype DSL”Here’s what using Effects looks like:
{-# LANGUAGE GADTs #-}{-# LANGUAGE FlexibleContexts #-}{-# LANGUAGE TypeOperators #-}{-# LANGUAGE DataKinds #-}module Teletype where
import Control.Monad.Effectimport Control.Monad.Effect.Internalimport 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 StringgetLine' = send GetLine
exitSuccess' :: Member Teletype r => Eff r ()exitSuccess' = send ExitSuccess
-------------------------------------------------------------------------------- -- Effectful Interpreter ----------------------------------------------------------------------------------runTeletype :: Eff '[Teletype] w -> IO wrunTeletype (Val x) = return xrunTeletype (E u q) = case decompose u of Right (PutStrLn msg) -> putStrLn msg >> runTeletype (apply q ()) Right GetLine -> getLine >>= \s -> runTeletype (apply 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 decompose u of Right (PutStrLn msg) -> go (x:xs) (apply q ()) (msg:acc) Right GetLine -> go xs (apply q x) acc Right ExitSuccess -> go xs (Val ()) acc Left _ -> go xs (Val ()) accContributing
Section titled “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. By participating in this project you agree to abide by its terms.
Developer Setup
Section titled “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 GHC
- stack build
- stack clean
- stack haddock : builds documentation
- stack test
- stack bench
- stack ghci : start a REPL instance
Licensing
Section titled “Licensing”This project is distributed under a BSD3 license. See the included LICENSE file for more details.
Acknowledgements
Section titled “Acknowledgements”This package would not be possible without the paper and the reference implementation. In particular:
- Data.Union maps to OpenUnion51.hs
- Data.FTCQueue maps to FTCQueue1
- Control.Monad.Effect* maps to Eff1.hs
There will be deviations from the source.