packages feed

effect-monad 0.7.0.0 → 0.8.0.0

raw patch · 12 files changed

+346/−81 lines, 12 filesdep ~type-level-setsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: type-level-sets

API changes (from Hackage documentation)

- Control.Effect.Helpers.List: instance forall k (k1 :: k) (xs :: [GHC.Types.*]) y j x. Control.Effect.Helpers.List.LookUpA k1 xs y => Control.Effect.Helpers.List.LookUpA k1 ((j, x) : xs) y
- Control.Effect.Parameterised: Id :: Morph a b
- Control.Effect.Parameterised: M :: a -> b -> Morph a b
- Control.Effect.Parameterised: T :: a -> T a
- Control.Effect.Parameterised: data Morph a b
- Control.Effect.Parameterised: instance Control.Effect.Effect Control.Effect.Parameterised.T
- Control.Effect.Parameterised: newtype T (i :: Morph * *) a
- Control.Effect.State: data Set (n :: [*]) :: [*] -> *
- Control.Effect.State: instance Control.Effect.State.Nubable '[e] '[e]
- Control.Effect.State: instance Control.Effect.State.Nubable (j Control.Effect.State.:-> (b Control.Effect.State.:! t) : as) as' => Control.Effect.State.Nubable (k Control.Effect.State.:-> (a Control.Effect.State.:! s) : j Control.Effect.State.:-> (b Control.Effect.State.:! t) : as) (k Control.Effect.State.:-> (a Control.Effect.State.:! s) : as')
- Control.Effect.State: instance Control.Effect.State.Nubable (k Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.RW) : as) as' => Control.Effect.State.Nubable (k Control.Effect.State.:-> (a Control.Effect.State.:! s) : k Control.Effect.State.:-> (a Control.Effect.State.:! t) : as) as'
- Control.Effect.State: instance Control.Effect.State.Nubable (k Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) as' => Control.Effect.State.Nubable (k Control.Effect.State.:-> (a Control.Effect.State.:! s) : k Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) as'
- Control.Effect.State: instance Control.Effect.State.Update '[e] '[e]
- Control.Effect.State: instance Control.Effect.State.Update (u Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) as' => Control.Effect.State.Update (v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R) : u Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) (v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R) : as')
- Control.Effect.State: instance Control.Effect.State.Update (u Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) as' => Control.Effect.State.Update (v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.W) : u Control.Effect.State.:-> (b Control.Effect.State.:! s) : as) as'
- Control.Effect.State: instance Control.Effect.State.Update (v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R) : as) as' => Control.Effect.State.Update (v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.W) : v Control.Effect.State.:-> (b Control.Effect.State.:! 'Control.Effect.State.R) : as) as'
- Control.Effect.State: instance Control.Effect.State.Update xs '[]
- Control.Effect.Writer: instance (GHC.Base.Monoid u, Data.Type.Map.Nubable (k 'Data.Type.Map.:-> u : s)) => Data.Type.Map.Nubable (k 'Data.Type.Map.:-> u : k 'Data.Type.Map.:-> u : s)
- Control.Effect.Writer: instance (GHC.Base.Monoid x, Control.Effect.Writer.Supermap '[] s) => Control.Effect.Writer.Supermap '[] (k 'Data.Type.Map.:-> x : s)
- Control.Effect.Writer: instance Control.Effect.Writer.Supermap s t => Control.Effect.Writer.Supermap (k 'Data.Type.Map.:-> v : s) (k 'Data.Type.Map.:-> v : t)
+ Control.Effect.Helpers.List: instance forall k1 (k2 :: k1) (xs :: [*]) y j x. Control.Effect.Helpers.List.LookUpA k2 xs y => Control.Effect.Helpers.List.LookUpA k2 ((j, x) : xs) y
+ Control.Effect.Parameterised: (>>) :: PMonad pm => pm pre mid t -> pm mid post t' -> pm pre post t'
+ Control.Effect.Parameterised: (>>=) :: PMonad pm => pm pre interm t -> (t -> pm interm post t') -> pm pre post t'
+ Control.Effect.Parameterised: class PMonad (pm :: k -> k -> * -> *)
+ Control.Effect.Parameterised: fail :: String -> m inv inv a
+ Control.Effect.Parameterised: ifThenElse :: Bool -> a -> a -> a
+ Control.Effect.Parameterised: return :: PMonad pm => a -> pm inv inv a
+ Control.Effect.Parameterised.AtomicState: State :: (s1 -> (a, s2)) -> State s1 s2 a
+ Control.Effect.Parameterised.AtomicState: [runState] :: State s1 s2 a -> s1 -> (a, s2)
+ Control.Effect.Parameterised.AtomicState: data Closed s
+ Control.Effect.Parameterised.AtomicState: data Open s
+ Control.Effect.Parameterised.AtomicState: get :: State (Closed s) (Open s) s
+ Control.Effect.Parameterised.AtomicState: instance GHC.Show.Show s => GHC.Show.Show (Control.Effect.Parameterised.AtomicState.Closed s)
+ Control.Effect.Parameterised.AtomicState: instance GHC.Show.Show s => GHC.Show.Show (Control.Effect.Parameterised.AtomicState.Open s)
+ Control.Effect.Parameterised.AtomicState: newtype State s1 s2 a
+ Control.Effect.Parameterised.AtomicState: put :: t -> State (Open s) (Closed t) ()
+ Control.Effect.Parameterised.ExtensibleState: (>>) :: PMonad pm => pm pre mid t -> pm mid post t' -> pm pre post t'
+ Control.Effect.Parameterised.ExtensibleState: (>>=) :: PMonad pm => pm pre interm t -> (t -> pm interm post t') -> pm pre post t'
+ Control.Effect.Parameterised.ExtensibleState: State :: (s1 -> (a, s2)) -> State s1 s2 a
+ Control.Effect.Parameterised.ExtensibleState: [runState] :: State s1 s2 a -> s1 -> (a, s2)
+ Control.Effect.Parameterised.ExtensibleState: class PMonad (pm :: k -> k -> * -> *)
+ Control.Effect.Parameterised.ExtensibleState: fail :: String -> m inv inv a
+ Control.Effect.Parameterised.ExtensibleState: get :: IsMember v t m => Var v -> State (Map m) (Map m) t
+ Control.Effect.Parameterised.ExtensibleState: ifThenElse :: Bool -> a -> a -> a
+ Control.Effect.Parameterised.ExtensibleState: modify :: (IsMember v s m, Updatable v t m n) => Var v -> (s -> t) -> State (Map m) (Map n) ()
+ Control.Effect.Parameterised.ExtensibleState: newtype State s1 s2 a
+ Control.Effect.Parameterised.ExtensibleState: put :: Updatable v t m n => Var v -> t -> State (Map m) (Map n) ()
+ Control.Effect.Parameterised.ExtensibleState: return :: PMonad pm => a -> pm inv inv a
+ Control.Effect.Parameterised.ExtensibleState: type Get v t m = IsMember v t m
+ Control.Effect.Parameterised.ExtensibleState: type Put v t m n = Updatable v t m n
+ Control.Effect.Parameterised.ExtensibleState: type Update v t m = (Get v t m, Put v t m m)
+ Control.Effect.Parameterised.SafeFiles: (>>) :: PMonad pm => pm pre mid t -> pm mid post t' -> pm pre post t'
+ Control.Effect.Parameterised.SafeFiles: (>>=) :: PMonad pm => pm pre interm t -> (t -> pm interm post t') -> pm pre post t'
+ Control.Effect.Parameterised.SafeFiles: class PMonad (pm :: k -> k -> * -> *)
+ Control.Effect.Parameterised.SafeFiles: data SafeFiles pre post a
+ Control.Effect.Parameterised.SafeFiles: data SafeHandle (n :: Nat)
+ Control.Effect.Parameterised.SafeFiles: data St (n :: Nat) (opens :: [Nat])
+ Control.Effect.Parameterised.SafeFiles: fail :: String -> m inv inv a
+ Control.Effect.Parameterised.SafeFiles: hClose :: Member h opens => SafeHandle h -> SafeFiles (St n opens) (St n (Delete h opens)) ()
+ Control.Effect.Parameterised.SafeFiles: hGetChar :: Member h opens => SafeHandle h -> SafeFiles (St n opens) (St n opens) Char
+ Control.Effect.Parameterised.SafeFiles: hIsEOF :: Member h opens => SafeHandle h -> SafeFiles (St n opens) (St n opens) Bool
+ Control.Effect.Parameterised.SafeFiles: hPutChar :: Member h opens => SafeHandle h -> Char -> SafeFiles (St n opens) (St n opens) ()
+ Control.Effect.Parameterised.SafeFiles: ifThenElse :: Bool -> a -> a -> a
+ Control.Effect.Parameterised.SafeFiles: instance Control.Effect.Parameterised.PMonad Control.Effect.Parameterised.SafeFiles.SafeFiles
+ Control.Effect.Parameterised.SafeFiles: instance Control.Effect.Parameterised.SafeFiles.Member x (x : xs)
+ Control.Effect.Parameterised.SafeFiles: instance Control.Effect.Parameterised.SafeFiles.Member x xs => Control.Effect.Parameterised.SafeFiles.Member x (y : xs)
+ Control.Effect.Parameterised.SafeFiles: openFile :: FilePath -> IOMode -> SafeFiles (St h opens) (St (h + 1) (h : opens)) (SafeHandle h)
+ Control.Effect.Parameterised.SafeFiles: return :: PMonad pm => a -> pm inv inv a
+ Control.Effect.Parameterised.SafeFiles: runSafeFiles :: SafeFiles (St 0 '[]) (St n '[]) () -> IO ()
+ Control.Effect.Parameterised.State: State :: (s1 -> (a, s2)) -> State s1 s2 a
+ Control.Effect.Parameterised.State: [runState] :: State s1 s2 a -> s1 -> (a, s2)
+ Control.Effect.Parameterised.State: instance Control.Effect.Parameterised.PMonad Control.Effect.Parameterised.State.State
+ Control.Effect.Parameterised.State: newtype State s1 s2 a
+ Control.Effect.ParameterisedAsGraded: Id :: Morph a b
+ Control.Effect.ParameterisedAsGraded: M :: a -> b -> Morph a b
+ Control.Effect.ParameterisedAsGraded: T :: a -> T a
+ Control.Effect.ParameterisedAsGraded: data Morph a b
+ Control.Effect.ParameterisedAsGraded: instance Control.Effect.Effect Control.Effect.ParameterisedAsGraded.T
+ Control.Effect.ParameterisedAsGraded: newtype T (i :: Morph * *) a
+ Control.Effect.State: data Set k (n :: [k]) :: forall k. () => [k] -> *
+ Control.Effect.State: data a (:!) (s :: Eff)
+ Control.Effect.State: instance Control.Effect.State.Nubable ((j Control.Effect.State.:-> (b Control.Effect.State.:! t)) : as) as' => Control.Effect.State.Nubable ((k Control.Effect.State.:-> (a Control.Effect.State.:! s)) : (j Control.Effect.State.:-> (b Control.Effect.State.:! t)) : as) ((k Control.Effect.State.:-> (a Control.Effect.State.:! s)) : as')
+ Control.Effect.State: instance Control.Effect.State.Update ((u Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) as' => Control.Effect.State.Update ((v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R)) : (u Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) ((v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R)) : as')
+ Control.Effect.State: instance forall k (e :: k). Control.Effect.State.Nubable '[e] '[e]
+ Control.Effect.State: instance forall k (e :: k). Control.Effect.State.Update '[e] '[e]
+ Control.Effect.State: instance forall k (u :: GHC.Types.Symbol) b (s :: Control.Effect.State.Eff) (as :: [*]) (as' :: [k]) (v :: GHC.Types.Symbol) a. Control.Effect.State.Update ((u Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) as' => Control.Effect.State.Update ((v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.W)) : (u Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) as'
+ Control.Effect.State: instance forall k (v :: GHC.Types.Symbol) a (as :: [*]) (as' :: [k]) b. Control.Effect.State.Update ((v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.R)) : as) as' => Control.Effect.State.Update ((v Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.W)) : (v Control.Effect.State.:-> (b Control.Effect.State.:! 'Control.Effect.State.R)) : as) as'
+ Control.Effect.State: instance forall k1 (k2 :: GHC.Types.Symbol) a (as :: [*]) (as' :: [k1]) (s :: Control.Effect.State.Eff) (t :: Control.Effect.State.Eff). Control.Effect.State.Nubable ((k2 Control.Effect.State.:-> (a Control.Effect.State.:! 'Control.Effect.State.RW)) : as) as' => Control.Effect.State.Nubable ((k2 Control.Effect.State.:-> (a Control.Effect.State.:! s)) : (k2 Control.Effect.State.:-> (a Control.Effect.State.:! t)) : as) as'
+ Control.Effect.State: instance forall k1 (k2 :: GHC.Types.Symbol) b (s :: Control.Effect.State.Eff) (as :: [*]) (as' :: [k1]) a. Control.Effect.State.Nubable ((k2 Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) as' => Control.Effect.State.Nubable ((k2 Control.Effect.State.:-> (a Control.Effect.State.:! s)) : (k2 Control.Effect.State.:-> (b Control.Effect.State.:! s)) : as) as'
+ Control.Effect.State: instance forall k1 k2 (xs :: [k2]). Control.Effect.State.Update xs '[]
+ Control.Effect.Writer: instance (GHC.Base.Monoid u, Data.Type.Map.Nubable ((k 'Data.Type.Map.:-> u) : s)) => Data.Type.Map.Nubable ((k 'Data.Type.Map.:-> u) : (k 'Data.Type.Map.:-> u) : s)
+ Control.Effect.Writer: instance (GHC.Base.Monoid x, Control.Effect.Writer.Supermap '[] s) => Control.Effect.Writer.Supermap '[] ((k 'Data.Type.Map.:-> x) : s)
+ Control.Effect.Writer: instance Control.Effect.Writer.Supermap s t => Control.Effect.Writer.Supermap ((k 'Data.Type.Map.:-> v) : s) ((k 'Data.Type.Map.:-> v) : t)
- Control.Coeffect: class Coeffect (c :: k -> * -> *) where type Inv c (s :: k) (t :: k) :: Constraint type Unit c :: k type Plus c (s :: k) (t :: k) :: k type Inv c s t = () where {
+ Control.Coeffect: class Coeffect (c :: k -> * -> *) where {
- Control.Coeffect: class CoeffectZip (c :: k -> * -> *) where type Meet c (s :: k) (t :: k) :: k type CzipInv c (s :: k) (t :: k) :: Constraint where {
+ Control.Coeffect: class CoeffectZip (c :: k -> * -> *) where {
- Control.Effect: (>>) :: (Effect m, Inv m f g) => m f a -> m g b -> m (Plus m f g) b
+ Control.Effect: (>>) :: (Effect m, (Inv m f g)) => m f a -> m g b -> m (Plus m f g) b
- Control.Effect: (>>=) :: (Effect m, Inv m f g) => m f a -> (a -> m g b) -> m (Plus m f g) b
+ Control.Effect: (>>=) :: (Effect m, (Inv m f g)) => m f a -> (a -> m g b) -> m (Plus m f g) b
- Control.Effect: class Effect (m :: k -> * -> *) where type Unit m :: k type Plus m (f :: k) (g :: k) :: k type Inv m (f :: k) (g :: k) :: Constraint type Inv m f g = () x >> y = x >>= (\ _ -> y) where {
+ Control.Effect: class Effect (m :: k -> * -> *) where {
- Control.Effect: fail :: a
+ Control.Effect: fail :: () => a
- Control.Effect.Cond: class Cond (m :: k -> * -> *) where type AltInv m (s :: k) (t :: k) :: Constraint type Alt m (s :: k) (t :: k) :: k type AltInv m s t = () where {
+ Control.Effect.Cond: class Cond (m :: k -> * -> *) where {
- Control.Effect.Helpers.List: class LookUpA k xs (LookupT k xs) => Lookup k xs where lookup = lookupA
+ Control.Effect.Helpers.List: class LookUpA k xs (LookupT k xs) => Lookup k xs
- Control.Effect.Reader: [Empty] :: Map ([] (Mapping Symbol *))
+ Control.Effect.Reader: [Empty] :: Map [] Mapping Symbol *
- Control.Effect.Reader: [Ext] :: Map ((:) (Mapping Symbol *) ((:->) Symbol * k v) m)
+ Control.Effect.Reader: [Ext] :: Map (:) Mapping Symbol * (:->) Symbol * k v m
- Control.Effect.State: [Empty] :: Set ([] *)
+ Control.Effect.State: [Empty] :: Set k [] k
- Control.Effect.State: [Ext] :: Set ((:) * e s)
+ Control.Effect.State: [Ext] :: Set * (:) * e s
- Control.Effect.State: class Sortable (xs :: [*])
+ Control.Effect.State: class Sortable k (xs :: [k])
- Control.Effect.State: class Split (s :: [*]) (t :: [*]) (st :: [*])
+ Control.Effect.State: class Split k k1 k2 (s :: [k]) (t :: [k1]) (st :: [k2])
- Control.Effect.State: data (:!) a (s :: Eff)
+ Control.Effect.State: data (k :: Symbol) (:->) (v :: *)
- Control.Effect.Writer: [Empty] :: Map ([] (Mapping Symbol *))
+ Control.Effect.Writer: [Empty] :: Map [] Mapping Symbol *
- Control.Effect.Writer: [Ext] :: Map ((:) (Mapping Symbol *) ((:->) Symbol * k v) m)
+ Control.Effect.Writer: [Ext] :: Map (:) Mapping Symbol * (:->) Symbol * k v m
- Control.Effect.Writer: type IsMap k v (s :: [Mapping k v]) = (~) [Mapping k v] s (Nub k v (Sort (Mapping k v) s))
+ Control.Effect.Writer: type IsMap k v (s :: [Mapping k v]) = (~) [Mapping k v] s Nub k v Sort Mapping k v s
- Control.Effect.Writer: type Union k v (m :: [Mapping k v]) (n :: [Mapping k v]) = Nub k v (Sort (Mapping k v) ((:++) (Mapping k v) m n))
+ Control.Effect.Writer: type Union k v (m :: [Mapping k v]) (n :: [Mapping k v]) = Nub k v Sort Mapping k v (:++) Mapping k v m n
- Control.Effect.Writer: type Unionable (s :: [Mapping Symbol *]) (t :: [Mapping Symbol *]) = (Nubable (Sort (Mapping Symbol *) ((:++) (Mapping Symbol *) s t)), Sortable ((:++) (Mapping Symbol *) s t))
+ Control.Effect.Writer: type Unionable (s :: [Mapping Symbol *]) (t :: [Mapping Symbol *]) = (Nubable Sort Mapping Symbol * (:++) Mapping Symbol * s t, Sortable (:++) Mapping Symbol * s t)
- Control.Effect.Writer: union :: Unionable s t => Map s -> Map t -> Map (Union Symbol * s t)
+ Control.Effect.Writer: union :: Unionable s t => Map s -> Map t -> Map Union Symbol * s t

Files

effect-monad.cabal view
@@ -1,20 +1,34 @@ name:                   effect-monad-version:                0.7.0.0-synopsis:               Embeds effect systems into Haskell using graded monads-description:            -   Provides the graded monad structure to Haskell with a number of analogs of familiar monads (Reader, Writer, State, Maybe, Counter, Update) and a wrapper over normal monads (Control.Effect.Monad). This provides a way to embed effect systems into Haskell. For more information see with paper \"Embedding effect systems in Haskell\" by Orchard and Petricek <http://www.cl.cam.ac.uk/~dao29/publ/haskell14-effects.pdf> (Haskell, 2014) and the examples in <https://github.com/dorchard/effect-monad/tree/master/examples>. -  (note, this package was previously called 'ixmonad' until September 2014). +version:                0.8.0.0+synopsis:               Embeds effect systems and program logics into Haskell using graded monads and parameterised monads+description:+   Provides the graded monad structure to Haskell via Control.Effect+   with a number of analogs of familiar monads and some new things:+        Reader, Writer, State, Maybe, Counter, Update +   and a wrapper over normal monads (Control.Effect.Monad). This provides a way+   to embed effect systems into Haskell. For more information see the paper+   \"Embedding effect systems in Haskell\" by Orchard and Petricek+   <http://dorchard.co.uk/publ/haskell14-effects.pdf> (Haskell, 2014)++   Also provides the parameterised monad structure due to Atkey in+   Control.Effect.Parameterised along with some instances:+       AtomicState, SafeFiles, ExtensibleState++   and the examples in <https://github.com/dorchard/effect-monad/tree/master/examples>.++  (note, this package was previously called 'ixmonad' until September 2014).+ license:                BSD3 license-file:           LICENSE category:               Control, Monads-copyright:              2013-16 University of Cambridge+copyright:              2013-18 University of Kent author:                 Dominic Orchard maintainer:             Dominic Orchard stability:              experimental build-type:             Simple cabal-version:          >= 1.6-tested-with:            GHC == 7.10.3, GHC == 8.0.1+tested-with:            GHC == 7.10.3, GHC == 8.0.1, GHC == 8.2.2  extra-source-files:     examples/*.hs @@ -35,15 +49,20 @@                         Control.Effect.CounterNat                         Control.Effect.Maybe                         Control.Effect.Monad-                        Control.Effect.Parameterised+                        Control.Effect.ParameterisedAsGraded                         Control.Effect.Reader                         Control.Effect.ReadOnceReader-                        Control.Effect.State	+                        Control.Effect.State                         Control.Effect.Update                         Control.Effect.Vector                         Control.Effect.WriteOnceWriter                         Control.Effect.Writer                         Control.Effect.Helpers.List-                        +                        Control.Effect.Parameterised+                        Control.Effect.Parameterised.AtomicState+                        Control.Effect.Parameterised.ExtensibleState+                        Control.Effect.Parameterised.SafeFiles+                        Control.Effect.Parameterised.State+   build-depends:        base < 5,-                        type-level-sets == 0.8.0.0+                        type-level-sets >= 0.8.7.0
+ examples/AtomicState.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE RebindableSyntax #-}++-- Bye Monads... as we know them+import Prelude hiding (Monad(..))+-- Hello parameterised monads+import Control.Effect.Parameterised+import Control.Effect.Parameterised.AtomicState++-----------------------------+-- Examples++myProgram :: State (Closed Int) (Closed Int) String+myProgram = do+  x <- get+  put (x+1)+  a <- somethingPurish x+  return (a ++ show x)++somethingPurish :: Int -> State (Closed Int) (Closed Int) String+somethingPurish n = do+  x <- get+  put (x + 1)+  return $ if n == 0 then "hello" else "goodbye"
+ examples/ExtensibleState.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}++import Prelude hiding (Monad(..))+import Control.Effect.Parameterised+import Control.Effect.Parameterised.ExtensibleState+import GHC.TypeLits+import Data.Type.Map++-- Example map+exMap :: Map '["x" ':-> Int, "flag" ':-> Bool]+exMap = Ext (Var @ "x") (42 :: Int)+      $ Ext (Var @ "flag") False+        Empty++increment :: (Update "x" Int m) => State (Map m) (Map m) ()+increment = do+   (n :: Int) <- get (Var @ "x")+   put (Var @ "x") (n+1)++example = do+   flag <- get (Var @ "flag")+   increment+   (n :: Int) <- get (Var @"x")+   put (Var @ "flag") ((n > 0) || flag)+++go :: ((), Map '["x" ':-> Int, "flag" ':-> Bool])+go = runState example exMap++example2 :: (Get "flag" Bool m, Update "x" Int m, Put "y" Int m m) => State (Map m) (Map m) ()+example2 = do+   flag <- get (Var @ "flag")+   if flag+     then modify (Var @ "x") (\(x :: Int) -> x + 1)+     else put (Var @ "y") (42 :: Int)
− examples/Inc.hs
@@ -1,35 +0,0 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeSynonymInstances #-}-module EffectsInHaskellProblem where--import           Control.Effect-import           Control.Effect.State-import           GHC.TypeLits-import           Prelude               hiding (log, Monad(..), (>>))--varX :: Var "x"-varX = Var--inc :: State '["x" :-> Int :! 'RW] ()-inc =-    get varX >>= (put varX . (+1))---- No instance for (Control.Effect.State.Nubable '["x" :-> (Int :! 'W)] '[])-inc2 =-    inc >>=-    \_ ->-         inc
+ examples/SafeFiles.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE FlexibleContexts #-}++-- Bye Monads... as we know them+import Prelude hiding (Monad(..))+import Control.Effect.Parameterised.SafeFiles+import qualified System.IO as IO++example :: IO ()+example = runSafeFiles $ do+  h  <- openFile "foo" IO.ReadWriteMode+  h' <- openFile "bar" IO.ReadWriteMode+  x <- hGetChar h+  hPutChar h' x+  hClose h'+  hClose h+  return ()++example2 :: IO ()+example2 = runSafeFiles $ do+  h1  <- openFile "foo" IO.ReadWriteMode+  h2 <- openFile "bar" IO.ReadWriteMode+  loopy h1 h2++loopy h1 h2 = do+  isEmpty <- hIsEOF h1+  if isEmpty+    then do+      hClose h1+      hClose h2+    else do+      x <- hGetChar h1+      hPutChar h2 x+      loopy h1 h2
− examples/WriterM.hs
@@ -1,17 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}--import Data.Monoid--data Writer w a = Writer { runWriter :: (a, w) }--instance Monoid w => Monad (Writer w) where-   return a = Writer (a, mempty)-   (Writer (a, w)) >>= k = let (b, w') = runWriter (k a)-                           in Writer (b, w `mappend` w')--instance Monad (Writer (Maybe a)) where-   return a = Writer (a, Nothing)-   (Writer (a, w)) >>= k = let (b, w') = runWriter (k a)-                           in case w' of -                                Nothing -> Writer (b, w)-                                Just w' -> Writer (b, Just w')
src/Control/Effect/Parameterised.hs view
@@ -1,25 +1,31 @@-{-# LANGUAGE KindSignatures, TypeFamilies, ConstraintKinds, PolyKinds, DataKinds #-}+-- Used to make the types extra clear+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-} -module Control.Effect.Parameterised where+-- This module implement parameterised monads due to Bob Atkey+-- (see 'Parameterised Notions of Computing' JFP 2009)+-- also defined in Control.Monad.Indexed (category-extras) -import Control.Effect+module Control.Effect.Parameterised ((>>), PMonad(..), fail, ifThenElse) where -{-| Implements Bob Atkey's 'parametric monads', -    and also the Control.Monad.Indexed package, by emulating-    indexing by morphisms -}+-- Bye Monads... as we know them+import Prelude hiding (Monad(..)) -{-| Data type of morphisms -}-newtype T (i :: Morph * *) a = T a+-- Hello Parameterised Monads+class PMonad (pm :: k -> k -> * -> *) where+  -- Lift pure values into effect-invariant computations+  return :: a -> pm inv inv a -{-| Data type denoting either a morphisms with source and target types, or identity -}-data Morph a b = M a b | Id+  -- Sequentially compose effectful computations+  (>>=) :: pm pre interm t -> (t -> pm interm post t') -> pm pre post t' -instance Effect (T :: ((Morph * *) -> * -> *)) where-    type Unit T = Id-    type Plus T (M a b) (M c d) = M a d-    type Plus T Id (M a b) = M a b-    type Plus T (M a b) Id = M a b-    type Inv  T (M a b) (M c d) = c ~ d+-- Other boilerplate+(>>) :: PMonad pm => pm pre mid t -> pm mid post t' -> pm pre post t'+x >> y = x >>= const y -    return a = T a-    (T x) >>= k = let T y = k x in T y+fail :: String -> m inv inv a+fail = error++ifThenElse :: Bool -> a -> a -> a+ifThenElse True x _ = x+ifThenElse False _ y = y
+ src/Control/Effect/Parameterised/AtomicState.hs view
@@ -0,0 +1,22 @@+-- For clarity in type classes instances+{-# LANGUAGE InstanceSigs #-}++module Control.Effect.Parameterised.AtomicState+        (get, put, Closed, Open, State(..)) where++-- Bye Monads... as we know them+import Prelude hiding (Monad(..))+-- Hello parameterised monads+import Control.Effect.Parameterised+import Control.Effect.Parameterised.State++newtype Closed s = Closed s deriving Show+newtype Open   s = Open s   deriving Show++-- get :: State s s+get :: State (Closed s) (Open s) s+get = State $ \(Closed s) -> (s, Open s)++-- put :: s -> State s ()+put :: t -> State (Open s) (Closed t) ()+put tx = State $ \(Open _) -> ((), Closed tx)
+ src/Control/Effect/Parameterised/ExtensibleState.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE RebindableSyntax #-}++module Control.Effect.Parameterised.ExtensibleState+          (State(..), Get, Put, Update, get, put, modify+          , PMonad(..), (>>), ifThenElse, fail) where++import Prelude hiding (Monad(..))+import Control.Effect.Parameterised+import Control.Effect.Parameterised.State+import Data.Type.Map++-- Fine-grained get, put, and modify+get :: IsMember v t m => Var v -> State (Map m) (Map m) t+get v = State $ \s -> (lookp v s, s)++put :: Updatable v t m n => Var v -> t -> State (Map m) (Map n) ()+put v t = State $ \s -> ((), update s v t)++modify :: (IsMember v s m, Updatable v t m n) => Var v -> (s -> t) -> State (Map m) (Map n) ()+modify v f = do+  x <- get v+  put v (f x)++-- Aliases for our operations+type Get v t m = IsMember v t m+type Put v t m n = Updatable v t m n+type Update v t m = (Get v t m, Put v t m m)
+ src/Control/Effect/Parameterised/SafeFiles.hs view
@@ -0,0 +1,99 @@+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}++{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}++module Control.Effect.Parameterised.SafeFiles+         (openFile, hGetChar, hPutChar, hClose, hIsEOF, runSafeFiles+         , SafeFiles, SafeHandle, St+         , PMonad(..), (>>), ifThenElse, fail) where++-- Bye Monads... as we know them+import Prelude hiding (Monad(..))+import Control.Effect.Parameterised++-- Import qualified versions of standard code we want to wrap+import qualified Prelude as P+import qualified System.IO as IO++import GHC.TypeLits -- gives us type-level natural numbers++{-++-- openFile :: FilePath -> IOMode -> IO Handle+-- hGetChar :: Handle -> IO Char+-- hPutChar :: Handle -> Char -> IO ()+-- hClose :: Handle -> IO ()++-- hIsOpen :: Handle -> IO Bool+-- hIsClosed :: Handle -> IO Bool++-}++-- Wrap the IO monad+newtype SafeFiles pre post a = SafeFiles { unSafeFiles :: IO a }++instance PMonad SafeFiles where+   -- return :: a -> SafeFiles p p a+   return = SafeFiles . P.return+   -- (>>=) :: SafeFiles p q a -> (a -> SafeFiles q r b) -> SafeFiles p r b+   (SafeFiles m) >>= k = SafeFiles (m P.>>= (unSafeFiles . k))++-- Safe handlers are indexed by a (unique) number+newtype SafeHandle (n :: Nat) =+       SafeHandle { unsafeHandle :: IO.Handle }++-- Protocol states are a pair of a type-level nat and list of naturals+data St (n :: Nat) (opens :: [Nat])++-- openFile :: FilePath -> IOMode -> IO Handle+-- Opens a file, returns a handler with a fresh name+openFile ::+    IO.FilePath+ -> IO.IOMode+ -> SafeFiles (St h opens) (St (h + 1) (h ': opens)) (SafeHandle h)+openFile f mode = SafeFiles $ fmap SafeHandle (IO.openFile f mode)++-- hClose :: Handle -> IO ()+hClose :: Member h opens =>+     SafeHandle h+  -> SafeFiles (St n opens) (St n (Delete h opens)) ()+hClose (SafeHandle h) = SafeFiles (IO.hClose h)++-- Delete a handler name from a list+type family Delete (n :: Nat) (ns :: [Nat]) where+            Delete n '[] = '[]+            Delete n (n ': ns) = ns+            Delete n (m ': ns) = m ': Delete n ns++-- Membership predicate+class Member (x :: Nat) (xs :: [Nat]) where+instance {-# OVERLAPS #-} Member x (x ': xs) where+instance Member x xs => Member x (y ': xs)++-- hGetChar :: Handle -> IO Char+hGetChar :: Member h opens =>+     SafeHandle h+  -> SafeFiles (St n opens) (St n opens) Char+hGetChar (SafeHandle h) = SafeFiles (IO.hGetChar h)++-- hPutChar :: Handle -> Char -> IO ()+hPutChar :: Member h opens =>+     SafeHandle h+  -> Char -> SafeFiles (St n opens) (St n opens) ()+hPutChar (SafeHandle h) c = SafeFiles (IO.hPutChar h c)++-- hIsEOF :: Handler -> IO Bool+hIsEOF :: Member h opens =>+  SafeHandle h -> SafeFiles (St n opens) (St n opens) Bool+hIsEOF (SafeHandle h) = SafeFiles (IO.hIsEOF h)++-- Only allow running when every file is closed at the end+runSafeFiles :: SafeFiles (St 0 '[]) (St n '[]) () -> IO ()+runSafeFiles = unSafeFiles
+ src/Control/Effect/Parameterised/State.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE InstanceSigs #-}++module Control.Effect.Parameterised.State where++-- Bye Monads... as we know them+import Prelude hiding (Monad(..))+import Control.Effect.Parameterised++newtype State s1 s2 a = State { runState :: s1 -> (a, s2) }++-- State parameterised monad+-- ... just like the+instance PMonad State where+  return :: a -> State s s a+  return x = State (\s -> (x, s))++  (>>=) :: State s1 s2 a -> (a -> State s2 s3 b) -> State s1 s3 b+  (State m) >>= k =+      State $ \s0 -> let (a, s1) = m s0+                         State m' = k a in m' s1
+ src/Control/Effect/ParameterisedAsGraded.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE KindSignatures, TypeFamilies, ConstraintKinds, PolyKinds, DataKinds #-}++module Control.Effect.ParameterisedAsGraded where++import Control.Effect++{-| Implements Bob Atkey's 'parametric monads',+    and also the Control.Monad.Indexed package, by emulating+    indexing by morphisms -}++{-| Data type of morphisms -}+newtype T (i :: Morph * *) a = T a++{-| Data type denoting either a morphisms with source and target types, or identity -}+data Morph a b = M a b | Id++instance Effect (T :: ((Morph * *) -> * -> *)) where+    type Unit T = Id+    type Plus T (M a b) (M c d) = M a d+    type Plus T Id (M a b) = M a b+    type Plus T (M a b) Id = M a b+    type Inv  T (M a b) (M c d) = c ~ d++    return a = T a+    (T x) >>= k = let T y = k x in T y