Name: multistate Version: 0.2.0.0 Cabal-Version: >= 1.10 Build-Type: Simple license: BSD3 license-file: LICENSE Copyright: Jan Bracker, Lennart Spitzner Maintainer: Lennart Spitzner Author: Jan Bracker, Lennart Spitzner Homepage: https://github.com/lspitzner/multistate Bug-reports: https://github.com/lspitzner/multistate/issues Stability: Experimental category: Control tested-with: GHC == 7.6.3, GHC == 7.8.3 Synopsis: like mtl's ReaderT/StateT, but more than one contained value/type. Description: . == Introduction . When using multiple ReaderT's or StateT's in the same monad stack, it becomes necessary to lift the operations in order to affect a specific transformer. Using heterogenous lists (type level functions), a GADT and a corresponding type class, this package provides transformers that remove that necessity: MultiReaderT/MultiStateT can contain a heterogenous list of values. . The type inferred for the getter/setter determines which value is read/written. . == Example . > simpleExample :: IO () > simpleExample = evalMultiStateT > $ withMultiState 'H' > $ withMultiState "ello, World!" > $ do > -- the monad here is MultiStateT '[String, Char] IO > let combinedPrint = do -- no type signature necessary > c <- mGet -- type of mGet inferred to be m Char > cs <- mGet -- inferred to be m String > lift $ putStrLn (c:cs) > combinedPrint > mSet 'J' -- similarly for the setter > combinedPrint . The output is: . > Hello, World! > Jello, World! . ( you can find both this and a more complex example in an executable in the package. ) . == Error Messages . If you try to execute an action that requires a specific type in the state, but the current state does not contain that type, the error message is something like . > No instance for (Control.Monad.MultiState.ContainsType Foo '[]) . where @Foo@ is the missing type. . == Known Deficits . This package currently lacks a complete set of "lifting instances", i.e. instance definitions for classes such as mtl's MonadWriter "over" the newly introduced monad transformers, as in . > instance (MonadWriter w m) => MonadWriter w (MultiStateT c m) where .. . These "lifting instances" would be necessary to achieve full compatability with existing transformers. Ping me if you find anything specific missing. . == Changelog . * 0.2.0.0: . * Start using DataKinds and TypeOperators to make the HList representation more readable. The translation roughly is: . > Null -> '[] > Cons a Null -> '[a] > Cons a b -> a ': b > TNull -> HNil > TCons a b -> a :+: b . * Remove dependency on `tfp` package. source-repository head type: git location: git@github.com:lspitzner/multistate.git flag build-test description: Build the MultiState-test test program default: False flag build-example description: Build the MultiState-example example program default: False library { default-language: Haskell2010 exposed-modules: Data.HList.HList Control.Monad.MultiState Control.Monad.MultiReader other-modules: build-depends: base >= 4.6 && <4.8, mtl >= 2.1 && <2.3, transformers >= 0.3 && <0.5 default-extensions: GADTs TypeFamilies MultiParamTypeClasses FunctionalDependencies FlexibleInstances OverlappingInstances UndecidableInstances TypeOperators DataKinds ghc-options: -Wall hs-source-dirs: src } executable multistate-test { default-language: Haskell2010 if flag(build-test) { buildable: True build-depends: -- no version constraints necessary, because they are already -- given by library multistate, base, transformers } else { buildable: False } ghc-options: -Wall main-is: Test.hs hs-source-dirs: test } executable multistate-example { default-language: Haskell2010 if flag(build-example) { buildable: True build-depends: -- no version constraints necessary, because they are already -- given by library multistate, base, mtl, transformers } else { buildable: False } main-is: Example.hs hs-source-dirs: example }