multistate-0.2.0.0: multistate.cabal
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 <lsp@informatik.uni-kiel.de>
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
}