packages feed

freer 0.2.2.5 → 0.2.2.6

raw patch · 3 files changed

+119/−1 lines, 3 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Control.Monad.Freer.Reader: asks :: (b -> a) -> Eff '[Reader b] a

Files

freer.cabal view
@@ -1,5 +1,5 @@ name:                freer-version:             0.2.2.5+version:             0.2.2.6 synopsis:            Implementation of the Freer Monad license:             BSD3 license-file:        LICENSE@@ -75,6 +75,7 @@   hs-source-dirs:   tests   main-is:          Tests.hs   other-modules:       Tests.Common+                     , Tests.Coroutine                      , Tests.Exception                      , Tests.Fresh                      , Tests.NonDetEff
src/Control/Monad/Freer/Reader.hs view
@@ -24,8 +24,15 @@   Reader(..),    ask,+  asks,   runReader,   local+  -- * Example 1: Simple Reader Usage+  -- $simpleReaderExample++  -- * Example 2: Modifying Reader Content With @local@+  -- $localExample+ ) where  import Control.Monad.Freer.Internal@@ -38,6 +45,10 @@ ask :: (Member (Reader e) r) => Eff r e ask = send Reader +-- | Request a value from the environment and applys as function+asks :: (b -> a) -> Eff '[Reader b] a+asks f = ask >>= return . f+ -- | Handler for reader effects runReader :: Eff (Reader e ': r) w -> e -> Eff r w runReader m e = handleRelay return (\Reader k -> k e) m@@ -54,3 +65,79 @@   let h :: Reader e v -> Arr r v a -> Eff r a       h Reader g = g e   interpose return h m+++{- $simpleReaderExample++In this example the @Reader@ monad 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'.++>import Control.Monad.Freer+>import Control.Monad.Freer.Reader+>import Data.Map as Map+>import Data.Maybe+>+>type Bindings = Map String Int+>+>asks :: (b -> a) -> Eff '[Reader b] a+>asks f = ask >>= return . f+>+>-- Returns True if the "count" variable contains correct bindings size.+>isCountCorrect :: Bindings -> Bool+>isCountCorrect bindings = run $ runReader calc_isCountCorrect bindings+>+>-- 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 = do+>    putStr $ "Count is correct for bindings " ++ (show sampleBindings) ++ ": "+>    putStrLn $ 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+>+> asks :: (b -> a) -> Eff '[Reader b] a+> asks f = ask >>= return . f+>+> 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 calculateModifiedContentLen s;+>     let len = run $ runReader calculateContentLen s ;+>     putStrLn $ "Modified 's' length: " ++ (show modifiedLen)+>     putStrLn $ "Original 's' length: " ++ (show len)+-}
+ tests/Tests/Coroutine.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DataKinds #-}++module Tests.Coroutine (+  runTestCoroutine+) where++import Control.Monad+import Control.Monad.Freer+import Control.Monad.Freer.Coroutine+import Control.Monad.Freer.State++runTestCoroutine :: [Int] -> Int+runTestCoroutine list = snd $ run $ runState effTestCoroutine 0+  where+    testCoroutine :: (Members '[Yield () Int, State Int] r) => Eff r ()+    testCoroutine = do+      -- yield for two elements and hope they're both odd+      b <- (&&)+        <$> yield () (even :: Int -> Bool)+        <*> yield () (even :: Int -> Bool)+      unless b (modify ((+1) :: Int -> Int) >> testCoroutine)++    effTestCoroutine = do+      status <- runC testCoroutine+      handleStatus list status+        where+          handleStatus _ Done = return ()+          handleStatus (i:is) (Continue () k) = k i >>= handleStatus is+          handleStatus [] _ = return ()