A friendly effect system for Haskell
Go to file
Alexis King 0bbe540c78 Add translate and translateM effect interpreter constructors
These simply help to avoid type annotations by providing some common
cases of effect interpreters.
2017-07-06 11:05:37 -07:00
bench Merge branch 'hlint-backport' into master 2017-04-16 17:02:31 +02:00
examples/src Completely change the exposed API for building effect handlers 2017-07-06 10:10:02 -07:00
src Add translate and translateM effect interpreter constructors 2017-07-06 11:05:37 -07:00
tests Fix hlint "Use module export list" warnings 2017-04-16 16:38:29 +02:00
.gitignore Generated .gitignore using GitHub snippets 2017-02-02 20:27:30 +01:00
.travis.yml Disable test-hlint flag for non-developer builds 2017-04-16 16:38:23 +02:00
changelog.md Add custom type errors for unsolvable Member constraints 2017-07-05 14:51:01 -07:00
freer-effects.cabal Make it easier to interpret actions in a polymorphic monad 2017-07-06 10:41:12 -07:00
LICENSE Renaming to freer-effects; updating copyright and package description 2017-02-02 20:06:51 +01:00
package.yaml Make it easier to interpret actions in a polymorphic monad 2017-07-06 10:41:12 -07:00
README.md Noting relationship with freer in package description 2017-03-21 15:29:33 +01:00
RELEASE.md Release Process: (ab)use merges to make releases reachable 2017-04-16 17:17:12 +02:00
Setup.hs initial commit 2015-09-12 00:38:18 -05:00

Freer Effects: Extensible Effects with Freer Monads

Haskell Programming Language BSD3 License

Hackage Stackage LTS 8 Stackage Nightly Hackage Dependencies Build

Description

Library freer-effects (actively maintained fork of freer) is an implementation of 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 are:

  • An efficient effect system for Haskell as a library.
  • Implementations for several common Haskell monads as effects:
    • Reader
    • Writer
    • State
    • StateRW: State in terms of Reader/Writer.
    • Trace
    • Exception
  • Core components for defining your own Effects.

Example: Console DSL

Here's what using Freer looks like:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module Console where

import Control.Monad.Freer
import Control.Monad.Freer.Internal
import System.Exit hiding (ExitSuccess)

--------------------------------------------------------------------------------
                               -- Effect Model --
--------------------------------------------------------------------------------
data Console s where
    PutStrLn    :: String -> Console ()
    GetLine     :: Console String
    ExitSuccess :: Console ()

putStrLn' :: Member Console r => String -> Eff r ()
putStrLn' = send . PutStrLn

getLine' :: Member Console r => Eff r String
getLine' = send GetLine

exitSuccess' :: Member Console r => Eff r ()
exitSuccess' = send ExitSuccess

--------------------------------------------------------------------------------
                          -- Effectful Interpreter --
--------------------------------------------------------------------------------
runConsole :: Eff '[Console] w -> IO w
runConsole (Val x) = return x
runConsole (E u q) =
    case extract u of
        PutStrLn msg -> putStrLn msg >>  runConsole (qApp q ())
        GetLine      -> getLine      >>= \s -> runConsole (qApp q s)
        ExitSuccess  -> exitSuccess

--------------------------------------------------------------------------------
                             -- Pure Interpreter --
--------------------------------------------------------------------------------
runConsolePure :: [String] -> Eff '[Console] w -> [String]
runConsolePure inputs req =
    reverse . snd $ run (handleRelayS (inputs, []) (\s _ -> pure s) go req)
  where
    go  :: ([String], [String])
        -> Console v
        -> (([String], [String]) -> Arr '[] v ([String], [String]))
        -> Eff '[] ([String], [String])
    go (is,   os) (PutStrLn msg) q = q (is, msg : os) ()
    go (i:is, os) GetLine        q = q (is, os) i
    go ([],   _ ) GetLine        _ = error "Not enough lines"
    go (_,    os) ExitSuccess    _ = pure ([], os)

Combining with Transformers

You already have some mtl code and are afraid that combining effects with your current tranformer stack would not be possible? Package freer-effects-extra has some mtl-related and other goodies.

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 compiler
  • stack build builds project, dependencies are automatically resolved
  • stack test builds project, its tests, and executes the tests
  • stack bench builds project, its benchmarks, and executes the benchamks
  • stack ghci start a REPL instance with a project modules loaded
  • stack clean
  • stack haddock builds documentation

For more information about stack tool can be found in its documentation.

Licensing

This project is distrubted under a BSD3 license. See the included LICENSE file for more details.

Acknowledgements

Package freer-effects started as a fork of freer authored by Allele Dev.

This package would not be possible without the paper and the reference implementation. In particular:

There will be deviations from the source.