Document change in semantics based on order of interpreters (#181)

* Polysemy.Internal: document change in semantics based on order of interpreters

* Polysemy.Internal: use new 'evalState' instead of mapping 'runState' in example

* Polysemy.Internal, DoctestSpec: properly support doctest

* Polysemy.Internal: small corrections
This commit is contained in:
TheMatten 2019-07-24 15:50:56 +02:00 committed by Sandy Maguire
parent c53357ca92
commit d803c81054
2 changed files with 55 additions and 0 deletions

View File

@ -40,6 +40,11 @@ import Polysemy.Internal.PluginLookup
import Polysemy.Internal.Union
-- $setup
-- >>> import Data.Function
-- >>> import Polysemy.State
-- >>> import Polysemy.Error
------------------------------------------------------------------------------
-- | The 'Sem' monad handles computations of arbitrary extensible effects.
-- A value of type @Sem r@ describes a program with the capabilities of
@ -72,6 +77,53 @@ import Polysemy.Internal.Union
-- is the order in which you call the interpreters that determines the
-- monomorphic representation of the @r@ parameter.
--
-- Order of interpreters can be important - it determines behaviour of effects
-- that manipulate state or change control flow. For example, when
-- interpreting this action:
--
-- >>> :{
-- example :: Members '[State String, Error String] r => Sem r String
-- example = do
-- put "start"
-- let throwing, catching :: Members '[State String, Error String] r => Sem r String
-- throwing = do
-- modify (++"-throw")
-- throw "error"
-- get
-- catching = do
-- modify (++"-catch")
-- get
-- catch @String throwing (\ _ -> catching)
-- :}
--
-- when handling 'Polysemy.Error.Error' first, state is preserved after error
-- occurs:
--
-- >>> :{
-- example
-- & runError
-- & fmap (either id id)
-- & evalState ""
-- & runM
-- & (print =<<)
-- :}
-- "start-throw-catch"
--
-- while handling 'Polysemy.State.State' first discards state in such cases:
--
-- >>> :{
-- example
-- & evalState ""
-- & runError
-- & fmap (either id id)
-- & runM
-- & (print =<<)
-- :}
-- "start-catch"
--
-- A good rule of thumb is to handle effects which should have \"global\"
-- behaviour over other effects later in the chain.
--
-- After all of your effects are handled, you'll be left with either
-- a @'Sem' '[] a@ or a @'Sem' '[ 'Embed' m ] a@ value, which can be
-- consumed respectively by 'run' and 'runM'.

View File

@ -23,6 +23,8 @@ spec = parallel $ describe "Error messages" $ it "should pass the doctest" $ doc
, "-XTypeOperators"
, "-XUnicodeSyntax"
, "-package type-errors"
#if __GLASGOW_HASKELL__ < 806
, "-XMonadFailDesugaring"
, "-XTypeInType"
@ -32,6 +34,7 @@ spec = parallel $ describe "Error messages" $ it "should pass the doctest" $ doc
-- Modules that are explicitly imported for this test must be listed here
, "src/Polysemy.hs"
, "src/Polysemy/Error.hs"
, "src/Polysemy/Output.hs"
, "src/Polysemy/Reader.hs"
, "src/Polysemy/Resource.hs"