-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReader.hs
59 lines (49 loc) · 1.76 KB
/
Reader.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- | Examples of the reader effect.
module Example.Reader where
-- base
import Control.Monad.IO.Class (MonadIO)
import Prelude hiding (print)
-- hspec
import Test.Hspec (Spec, it, shouldBe)
-- effet
import Control.Effect.Identity
import Control.Effect.Reader
import Hspec (print, shouldPrint)
--- Example Programs -----------------------------------------------------------
-- | Returns the triple of the number in the reader.
triple :: Reader Int m => m Int
triple = do
single <- ask
double <- asks (*2)
pure $ single + double
-- | Prints the triple and sixfold of the number in the reader.
printTripleSix :: (MonadIO m, Reader Int m) => m ()
printTripleSix = do
t <- triple
s <- local (*2) triple
print t
print s
-- | Prints the double of reader "bar" and the triple of reader "foo".
printFooBar :: (MonadIO m, Reader' "bar" Int m, Reader' "foo" Int m) => m ()
printFooBar =
local' @"bar" (*2) $
local' @"foo" (*3) $ do
ask' @"bar" >>= print
ask' @"foo" >>= print
--- Test Cases -----------------------------------------------------------------
spec :: Spec
spec = do
it "evaluates triple" $
( runIdentity -- result: Int
. runReader 22 -- result: Monad m => m Int
$ triple ) -- effects: Reader Int
`shouldBe` 66
it "evaluates printTripleSix" $
runReader 10 -- result: MonadIO m => m (), unified with IO ()
printTripleSix -- effects: MonadIO, Reader Int
`shouldPrint` "30\n60\n"
it "evaluates printFooBar" $
( runReader' @"bar" 20 -- result: MonadIO m => m (), unified with IO ()
. runReader' @"foo" 50 -- effects: MonadIO, Reader' "bar" Int
$ printFooBar -- effects: MonadIO, Reader' "bar" Int, Reader' "foo" Int
) `shouldPrint` "40\n150\n"