Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Control/Monad/Freer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ implemented in-memory in terms of 'Control.Monad.Freer.State.State'. With
runInMemoryFileSystem :: [('FilePath', 'String')] -> 'Eff' (FileSystem ': effs) '~>' 'Eff' effs
runInMemoryFileSystem initVfs = 'Control.Monad.Freer.State.evalState' initVfs '.' fsToState where
fsToState :: 'Eff' (FileSystem ': effs) '~>' 'Eff' ('Control.Monad.Freer.State.State' [('FilePath', 'String')] ': effs)
fsToState = 'reinterpret' '$' \case
fsToState = 'reinterpret' '$' \\case
ReadFile path -> 'Control.Monad.Freer.State.get' '>>=' \\vfs -> case 'lookup' path vfs of
'Just' contents -> 'pure' contents
'Nothing' -> 'error' ("readFile: no such file " ++ path)
Expand Down
5 changes: 4 additions & 1 deletion src/Control/Monad/Freer/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,12 @@ raise = loop
-- Nondeterministic Choice --
--------------------------------------------------------------------------------

-- | A data type for representing nondeterminstic choice.
-- | A data type for representing nondeterministic choice.
data NonDet a where
-- | Terminates the current branch of the computation.
MZero :: NonDet a
-- | Splits the computation into two branches,
-- producing 'True' in one branch and 'False' in the other.
MPlus :: NonDet Bool

instance Member NonDet effs => Alternative (Eff effs) where
Expand Down
4 changes: 3 additions & 1 deletion src/Control/Monad/Freer/NonDet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Control.Monad.Freer.Internal
, tsingleton
)

-- | A handler for nondeterminstic effects.
-- | A handler for nondeterministic effects.
makeChoiceA
:: Alternative f
=> Eff (NonDet ': effs) a
Expand All @@ -38,6 +38,8 @@ makeChoiceA = handleRelay (pure . pure) $ \m k ->
MZero -> pure empty
MPlus -> (<|>) <$> k True <*> k False

-- | Attempt to split the nondeterministic computation into its
-- first result and the remainder of the computation.
msplit
:: Member NonDet effs
=> Eff effs a
Expand Down
115 changes: 57 additions & 58 deletions src/Control/Monad/Freer/Reader.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ data Reader r a where
ask :: forall r effs. Member (Reader r) effs => Eff effs r
ask = send Ask

-- | Request a value of the environment, and apply as selector\/projection
-- | Request a value of the environment, and apply a selector\/projection
-- function to it.
asks
:: forall r effs a
Expand Down Expand Up @@ -72,66 +72,65 @@ local f m = do
--
-- In this example the 'Reader' effect provides access to variable bindings.
-- Bindings are a @Map@ of integer variables. The variable @count@ contains
-- number of variables in the bindings. You can see how to run a Reader effect
-- and retrieve data from it with 'runReader', how to access the Reader data
-- with 'ask' and 'asks'.
-- the number of variables in the bindings. You can see how to run a @Reader@
-- effect and retrieve data from it with 'runReader', and how to access the
-- @Reader@ data with 'ask' and 'asks'.
--
-- > import Control.Monad.Freer
-- > import Control.Monad.Freer.Reader
-- > import Data.Map as Map
-- > import Data.Maybe
-- >
-- > type Bindings = Map String Int
-- >
-- > -- Returns True if the "count" variable contains correct bindings size.
-- > isCountCorrect :: Bindings -> Bool
-- > isCountCorrect bindings = run $ runReader bindings calc_isCountCorrect
-- >
-- > -- The Reader effect, which implements this complicated check.
-- > calc_isCountCorrect :: Eff '[Reader Bindings] Bool
-- > calc_isCountCorrect = do
-- > count <- asks (lookupVar "count")
-- > bindings <- (ask :: Eff '[Reader Bindings] Bindings)
-- > return (count == (Map.size bindings))
-- >
-- > -- The selector function to use with 'asks'.
-- > -- Returns value of the variable with specified name.
-- > lookupVar :: String -> Bindings -> Int
-- > lookupVar name bindings = fromJust (Map.lookup name bindings)
-- >
-- > sampleBindings :: Map.Map String Int
-- > sampleBindings = Map.fromList [("count",3), ("1",1), ("b",2)]
-- >
-- > main :: IO ()
-- > main = putStrLn
-- > $ "Count is correct for bindings " ++ show sampleBindings ++ ": "
-- > ++ show (isCountCorrect sampleBindings)
-- @
-- import Control.Monad.Freer
-- import Control.Monad.Freer.Reader
-- import Data.Map (Map, (!))
-- import qualified Data.Map as Map
--
-- type Bindings = Map String Int
--
-- -- Returns whether the "count" variable contains the correct bindings size.
-- isCountCorrect :: Bindings -> Bool
-- isCountCorrect bindings = run $ 'runReader' bindings checkCount
--
-- -- The Reader effect, which implements this complicated check.
-- checkCount :: 'Eff' \'['Reader' Bindings] Bool
-- checkCount = do
-- count <- 'asks' (lookupVar "count")
-- bindings <- ('ask' :: Eff \'[Reader Bindings] Bindings)
-- return (count == Map.size bindings)
--
-- -- The selector function to use with 'asks'.
-- -- Returns the value of the variable with specified name.
-- lookupVar :: String -> Bindings -> Int
-- lookupVar name bindings = bindings ! name
--
-- sampleBindings :: Bindings
-- sampleBindings = Map.fromList [("count", 3), ("1", 1), ("b", 2)]
--
-- main :: IO ()
-- main = putStrLn
-- $ "Count is correct for bindings " ++ show sampleBindings ++ ": "
-- ++ show (isCountCorrect sampleBindings)
-- @

-- $localExample
--
-- Shows how to modify 'Reader' content with 'local'.
--
-- > import Control.Monad.Freer
-- > import Control.Monad.Freer.Reader
-- >
-- > import Data.Map as Map
-- > import Data.Maybe
-- >
-- > type Bindings = Map String Int
-- >
-- > calculateContentLen :: Eff '[Reader String] Int
-- > calculateContentLen = do
-- > content <- (ask :: Eff '[Reader String] String)
-- > return (length content)
-- >
-- > -- Calls calculateContentLen after adding a prefix to the Reader content.
-- > calculateModifiedContentLen :: Eff '[Reader String] Int
-- > calculateModifiedContentLen = local ("Prefix " ++) calculateContentLen
-- >
-- > main :: IO ()
-- > main = do
-- > let s = "12345"
-- > let modifiedLen = run $ runReader s calculateModifiedContentLen
-- > let len = run $ runReader s calculateContentLen
-- > putStrLn $ "Modified 's' length: " ++ (show modifiedLen)
-- > putStrLn $ "Original 's' length: " ++ (show len)
-- @
-- import Control.Monad.Freer
-- import Control.Monad.Freer.Reader
--
-- calculateContentLen :: 'Eff' \'['Reader' String] Int
-- calculateContentLen = do
-- content <- ('ask' :: Eff \'[Reader String] String)
-- return (length content)
--
-- -- Calls calculateContentLen after adding a prefix to the Reader content.
-- calculateModifiedContentLen :: Eff \'[Reader String] Int
-- calculateModifiedContentLen = 'local' ("Prefix " ++) calculateContentLen
--
-- main :: IO ()
-- main = do
-- let s = "12345"
-- let modifiedLen = run $ 'runReader' s calculateModifiedContentLen
-- let len = run $ runReader s calculateContentLen
-- putStrLn $ "Modified \'s\' length: " ++ (show modifiedLen)
-- putStrLn $ "Original \'s\' length: " ++ (show len)
-- @
4 changes: 2 additions & 2 deletions src/Control/Monad/Freer/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
-- Composable handler for 'State' effects. Handy for passing an updatable state
-- through a computation.
--
-- Some computations may not require the full power of 'State' effect:
-- Some computations may not require the full power of the 'State' effect:
--
-- * For a read-only state, see "Control.Monad.Freer.Reader".
-- * To accumulate a value without using it on the way, see
Expand Down Expand Up @@ -57,7 +57,7 @@ get = send Get
put :: forall s effs. Member (State s) effs => s -> Eff effs ()
put s = send (Put s)

-- | Modify the current state of type @s :: *@ using provided function
-- | Modify the current state of type @s :: *@ using the provided function
-- @(s -> s)@.
modify :: forall s effs. Member (State s) effs => (s -> s) -> Eff effs ()
modify f = fmap f get >>= put
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Freer/TH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ makeEffect = genFreer True
--
-- -- | Output a string.
-- output :: Member Lang effs
-- => String -- ^ String to output.
-- => String -- ^ String to output.
-- -> Eff effs () -- ^ No result.
-- @
--
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Freer/Trace.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
-- Portability: GHC specific language extensions.
--
-- Composable handler for 'Trace' effects. Trace allows one to debug the
-- operation of sequences of effects by outputing to the console.
-- operation of sequences of effects by outputting to the console.
--
-- Using <http://okmij.org/ftp/Haskell/extensible/Eff1.hs> as a starting point.
module Control.Monad.Freer.Trace
Expand Down
6 changes: 3 additions & 3 deletions src/Control/Monad/Freer/Writer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
-- Portability: GHC specific language extensions.
--
-- 'Writer' effects, for writing\/appending values (line count, list of
-- messages, etc.) to an output. Current value of 'Writer' effect output is not
-- accessible to the computation.
-- messages, etc.) to an output. The current value of the 'Writer' effect output
-- is not accessible to the computation.
--
-- Using <http://okmij.org/ftp/Haskell/extensible/Eff1.hs> as a starting point.
module Control.Monad.Freer.Writer
Expand All @@ -28,7 +28,7 @@ import Data.Monoid ((<>))

import Control.Monad.Freer.Internal (Eff, Member, handleRelay, send)

-- | Writer effects - send outputs to an effect environment.
-- | Writer effects: send outputs to an effect environment.
data Writer w r where
Tell :: w -> Writer w ()

Expand Down