-
Notifications
You must be signed in to change notification settings - Fork 39
/
NullObject.hs
112 lines (89 loc) · 3.16 KB
/
NullObject.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
module NullObject where
import Control.Monad ((>=>))
import Data.Map (Map, fromList)
import qualified Data.Map as Map (lookup)
type Song = String
type Album = String
type Artist = String
type URL = String
songMap :: Map Song Album
songMap = fromList
[("Baby Satellite","Microgravity")
,("An Ending", "Apollo: Atmospheres and Soundtracks")]
albumMap :: Map Album Artist
albumMap = fromList
[("Microgravity","Biosphere")
,("Apollo: Atmospheres and Soundtracks", "Brian Eno")]
artistMap :: Map Artist URL
artistMap = fromList
[("Biosphere","http://www.biosphere.no//")
,("Brian Eno", "http://www.brian-eno.net")]
loookup' :: Ord a => Map a b -> a -> Maybe b
loookup' = flip Map.lookup
findAlbum :: Song -> Maybe Album
findAlbum = loookup' songMap
findArtist :: Album -> Maybe Artist
findArtist = loookup' albumMap
findWebSite :: Artist -> Maybe URL
findWebSite = loookup' artistMap
findUrlFromSong :: Song -> Maybe URL
findUrlFromSong song =
case findAlbum song of
Nothing -> Nothing
Just album ->
case findArtist album of
Nothing -> Nothing
Just artist ->
case findWebSite artist of
Nothing -> Nothing
Just url -> Just url
findUrlFromSongDo :: Song -> Maybe URL
findUrlFromSongDo song = do
album <- findAlbum song
artist <- findArtist album
findWebSite artist
findUrlFromSong' :: Song -> Maybe URL
findUrlFromSong' song =
findAlbum song >>= \album ->
findArtist album >>= \artist ->
findWebSite artist
findUrlFromSong'' :: Song -> Maybe URL
findUrlFromSong'' song =
findAlbum song >>= findArtist >>= findWebSite
findUrlFromSong''' :: Song -> Maybe URL
findUrlFromSong''' =
findAlbum >=> findArtist >=> findWebSite
nullObjectDemo = do
putStrLn "NullObject -> Maybe"
print $ Map.lookup "Baby Satellite" songMap
print $ Map.lookup "The Fairy Tale" songMap
case Map.lookup "Ancient Campfire" songMap of
Nothing -> print "sorry, could not find your song"
Just s -> print s
print $ findUrlFromSong' "An Ending"
print $ findUrlFromSong'' "Baby Satellite"
print $ findUrlFromSong''' "A Never Ending Story"
print $ safeRootReciprocal 0
print $ safeRootReciprocal (-10)
print $ safeRootReciprocal 0.01
{-- --This is how >=> could be implemented for Maybe:
(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
m1 >=> m2 = \x ->
case m1 x of
Nothing -> Nothing
Just y -> case m2 y of
Nothing -> Nothing
result@(Just z) -> result
--}
safeRoot :: Double -> Maybe Double
safeRoot x
| x >= 0 = Just (sqrt x)
| otherwise = Nothing
safeReciprocal :: Double -> Maybe Double
safeReciprocal x
| x /= 0 = Just (1/x)
| otherwise = Nothing
safeRootReciprocal :: Double -> Maybe Double
safeRootReciprocal = safeReciprocal >=> safeRoot
safeRootReciprocal' :: Double -> Maybe Double
safeRootReciprocal' x = return x >>= safeReciprocal >>= safeRoot