-
Notifications
You must be signed in to change notification settings - Fork 0
/
MaybeSpec.hs
82 lines (68 loc) · 2.55 KB
/
MaybeSpec.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module MaybeSpec where
import Test.Hspec
data User = User [Char] [Char] deriving (Show, Eq)
alice :: User
alice = User "Alice" "alicePassword"
searchForUserNamed :: [Char] -> Maybe User
searchForUserNamed name =
if name == "Alice"
then Just alice
else Nothing
searchAndDisplayResultAsString :: [Char] -> [Char]
searchAndDisplayResultAsString name =
case searchResult of
(Just (User _ password)) -> "found user " ++ name ++ " with password " ++ password
Nothing -> "did not find user " ++ name
where searchResult = searchForUserNamed name
newtype Baz = Baz (Maybe Integer)
newtype Bar = Bar (Maybe Baz)
newtype Foo = Foo (Maybe Bar)
withPatternMatch :: Maybe Foo -> Maybe Integer
withPatternMatch maybeFoo =
case maybeFoo of
Just (Foo maybeBar) -> case maybeBar of
Just (Bar maybeBaz) -> case maybeBaz of
Just (Baz maybeValue) -> case maybeValue of
Just value -> Just (value * 2)
Nothing -> Nothing
Nothing -> Nothing
Nothing -> Nothing
Nothing -> Nothing
withDoBlock :: (Maybe Foo) -> (Maybe Integer)
withDoBlock maybeFoo = do
Foo maybeBar <- maybeFoo
Bar maybeBaz <- maybeBar
Baz maybeValue <- maybeBaz
value <- maybeValue
pure (value * 2)
withBind :: (Maybe Foo) -> (Maybe Integer)
withBind maybeFoo =
maybeFoo >>= \(Foo maybeBar) ->
maybeBar >>= \(Bar maybeBaz) ->
maybeBaz >>= \(Baz maybeValue) ->
maybeValue >>= \value -> pure (value * 2)
spec :: Spec
spec = do
it "find user by name" $ do
searchForUserNamed "Alice" `shouldBe` Just alice
it "search for user by name but don't find" $ do
searchForUserNamed "Bob" `shouldBe` Nothing
it "display search result when found" $ do
let actual = searchAndDisplayResultAsString "Alice"
expected = "found user Alice with password alicePassword"
actual `shouldBe` expected
it "display search result when not found" $ do
let actual = searchAndDisplayResultAsString "Bob"
expected = "did not find user Bob"
actual `shouldBe` expected
it "multiply the target value by 2 if it exists" $ do
let testValues =
[ Nothing
, Just (Foo Nothing)
, Just (Foo (Just (Bar Nothing)))
, Just (Foo (Just (Bar (Just (Baz Nothing)))))
, Just (Foo (Just (Bar (Just (Baz (Just 1234))))))
]
map withPatternMatch testValues `shouldBe` [Nothing, Nothing, Nothing, Nothing, Just 2468]
map withDoBlock testValues `shouldBe` [Nothing, Nothing, Nothing, Nothing, Just 2468]
map withBind testValues `shouldBe` [Nothing, Nothing, Nothing, Nothing, Just 2468]