packages feed

extensible-effects 1.9.0.1 → 1.9.1.0

raw patch · 5 files changed

+139/−5 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Eff.Operational: Program :: (instr a) -> (a -> v) -> Program instr v
+ Control.Eff.Operational: data Program instr v
+ Control.Eff.Operational: instance Functor (Program instr)
+ Control.Eff.Operational: instance Typeable Program
+ Control.Eff.Operational: runProgram :: Typeable f => (forall x. f x -> Eff r x) -> Eff (Program f :> r) a -> Eff r a
+ Control.Eff.Operational: singleton :: (Typeable instr, Member (Program instr) r) => instr a -> Eff r a
+ Control.Eff.Operational.Example: Print :: String -> Jail ()
+ Control.Eff.Operational.Example: Scan :: Jail String
+ Control.Eff.Operational.Example: adventIO :: (Member (Lift IO) r, SetMember Lift (Lift IO) r) => Jail a -> Eff r a
+ Control.Eff.Operational.Example: adventPure :: (Member (Writer String) r, Member (State [String]) r) => Jail a -> Eff r a
+ Control.Eff.Operational.Example: data Jail a
+ Control.Eff.Operational.Example: instance Typeable Jail
+ Control.Eff.Operational.Example: prog :: Member (Program Jail) r => Eff r ()

Files

README.md view
@@ -2,15 +2,18 @@ [Extensible Effects: An Alternative to Monad Transformers](http://okmij.org/ftp/Haskell/extensible/). Please read the [paper](http://okmij.org/ftp/Haskell/extensible/exteff.pdf) for details. -[![Build Status](https://travis-ci.org/bfops/extensible-effects.svg?branch=master)](https://travis-ci.org/bfops/extensible-effects)+[![Build Status](https://travis-ci.org/suhailshergill/extensible-effects.svg?branch=master)](https://travis-ci.org/suhailshergill/extensible-effects)+[![Join the chat at https://gitter.im/suhailshergill/extensible-effects](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/suhailshergill/extensible-effects?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)  ## Advantages +   * Effects can be added, removed, and interwoven without changes to code not     dealing with those effects.  ## Disadvantages +### For GHC version 7.8 and upwards   * Common functions can't be grouped using typeclasses, e.g.     the `ask` and `getState` functions can't be grouped with some @@ -21,9 +24,11 @@     a constraint on `t`, and nothing more. To specify fully, a parameter     involving the type `t` would need to be added, which would defeat the point     of having the grouping in the first place.-   * Requires a `Typeable` instance on the return type. This is no longer a     limitation on GHC versions 7.8 and above.+    * fixed by https://github.com/suhailshergill/extensible-effects/issues/38++### For GHC versions prior to 7.8   * Neither `Eff` nor `(:>)` has a `Typeable` instance, and can thus often not-    be used as a return type (e.g. `State` type) for other `Eff`s. This is no-    longer a concern for GHC versions 7.8 and above.+    be used as a return type (e.g. `State` type) for other `Eff`s. +    * fixed by https://github.com/suhailshergill/extensible-effects/issues/38
extensible-effects.cabal view
@@ -6,7 +6,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             1.9.0.1+version:             1.9.1.0  -- A short (one-line) description of the package. synopsis:            An Alternative to Monad Transformers@@ -72,6 +72,8 @@                        Control.Eff.Writer.Lazy                        Control.Eff.Writer.Strict                        Control.Eff.Trace+                       Control.Eff.Operational+                       Control.Eff.Operational.Example                        Control.Monad.Free.Reflection                        Data.OpenUnion 
+ src/Control/Eff/Operational.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}++-- | Operational Monad (<https://wiki.haskell.org/Operational>) implemented with+-- extensible effects.++module Control.Eff.Operational ( Program (..)+                               , singleton+                               , runProgram+                               -- * Usage+                               -- $usage+                               ) where++import Data.Typeable+import Control.Eff++#if MIN_VERSION_base(4,7,0)+#define Typeable1 Typeable+#endif++-- | Lift values to an effect.+-- You can think this is a generalization of @Lift@.+data Program instr v = forall a. Program (instr a) (a -> v)+#if MIN_VERSION_base(4,7,0)+         deriving (Typeable) -- starting from ghc-7.8 Typeable can only be derived+#else++instance Typeable1 instr => Typeable1 (Program instr) where+    typeOf1 _ = mkTyConApp (mkTyCon3+                            "extensible-effects"+                            "Control.Eff.Operational"+                            "Program")+                           [typeOf1 (undefined :: instr ())]+#endif++instance Functor (Program instr) where+    fmap f (Program instr k) = Program instr (f . k)++-- | Lift a value to a monad.+singleton :: (Typeable1 instr, Member (Program instr) r) => instr a -> Eff r a+singleton instr = send . inj $ (Program instr) id++-- | Convert values using given interpreter to effects.+runProgram :: Typeable1 f => (forall x. f x -> Eff r x) -> Eff (Program f :> r) a -> Eff r a+runProgram advent = loop where+  loop = freeMap+         return+         (\u -> handleRelay u loop (\ (Program instr k) -> advent instr >>= loop . k))+++-- $usage+--+-- See 'Control.Eff.Operational.Example' for an example of defining data using+-- GADTs and implementing interpreters from the data to effects.+--+-- To use the interpreter, see below or consult the tests.+--+-- @+--main :: IO ()+--main = do+--    putStrLn . fst . 'run' . 'runMonoidWriter' . 'evalState' [\"foo\",\"bar\"] $ 'runProgram' adventPure prog+--    'runLift' $ 'runProgram' adventIO prog+-- @
+ src/Control/Eff/Operational/Example.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE CPP #-}++module Control.Eff.Operational.Example where++import Control.Eff.Operational+import Control.Eff+import Control.Eff.Lift+import Control.Eff.Writer.Lazy+import Control.Eff.State.Lazy+import Data.Typeable++#if MIN_VERSION_base(4,7,0)+#define Typeable1 Typeable+#endif++-- | Define data using GADTs.+data Jail a where+   Print :: String -> Jail ()+   Scan :: Jail String+    deriving (Typeable)++prog :: Member (Program Jail) r => Eff r ()+prog = do+   singleton $ Print "getting input..."+   str <- singleton Scan+   singleton $ Print "ok"+   singleton $ Print ("the input is " ++ str)++-- | Then, implements interpreters from the data to effects.+adventIO :: (Member (Lift IO) r, SetMember Lift (Lift IO) r) => Jail a -> Eff r a+adventIO (Print a) = lift $ putStrLn a+adventIO Scan = lift getLine++adventPure :: (Member (Writer String) r, Member (State [String]) r) => Jail a -> Eff r a+adventPure (Print a) = tell (a ++ "\n")+adventPure Scan = do+  x <- get+  case x of+    [] -> return []+    y:ys -> put ys >> return y
test/Test.hs view
@@ -15,6 +15,8 @@ import Control.Eff import Control.Eff.Exception import Control.Eff.Lift+import Control.Eff.Operational as Op+import Control.Eff.Operational.Example as Op.Eg import Control.Eff.Reader.Lazy as LazyR import Control.Eff.State.Lazy as LazyS import Control.Eff.Writer.Lazy as LazyW@@ -178,6 +180,18 @@       return x #endif +testOperational :: Assertion+testOperational =+  let comp :: (Member (LazyS.State [String]) r+               , Member (LazyW.Writer String) r)+              => Eff r ()+      comp = Op.runProgram Op.Eg.adventPure Op.Eg.prog+      go = fst . run . LazyW.runMonoidWriter . LazyS.evalState ["foo", "bar"] $ comp+  in+   assertEqual+   "Evaluating Operational Monad example"+   "getting input...\nok\nthe input is foo\n" go+ tests =   [ testProperty "Documentation example." testDocs   , testProperty "Test Writer.Lazy.censor." testCensor@@ -193,4 +207,5 @@ #if __GLASGOW_HASKELL__ >= 708   , testProperty "Test nested Eff." testNestedEff #endif+  , testCase "Test Operational monad." testOperational   ]