-
Notifications
You must be signed in to change notification settings - Fork 0
/
chap18.hs
65 lines (50 loc) · 1.46 KB
/
chap18.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
module Chap18 where
import Control.Monad
-- years ago
type Founded = Int
-- number of programmers
type Coders = Int
data SoftwareShop =
Shop {
founded :: Founded
, programmers :: Coders
} deriving (Eq, Show)
data FoundedError =
NegativeYears Founded
| TooManyYears Founded
| NegativeCoders Coders
| TooManyCoders Coders
| TooManyCodersForYears Founded Coders
deriving (Eq, Show)
validateFounded :: Int -> Either FoundedError Founded
validateFounded n
| n < 0 = Left $ NegativeYears n
| n > 500 = Left $ TooManyYears n
| otherwise = Right n
validateCoders :: Int -> Either FoundedError Coders
validateCoders n
| n < 0 = Left $ NegativeCoders n
| n > 5000 = Left $ TooManyCoders n
| otherwise = Right n
mkSoftware :: Int -> Int -> Either FoundedError SoftwareShop
mkSoftware years coders = do
founded <- validateFounded years
programmers <- validateCoders coders
if programmers > div founded 10
then Left $ TooManyCodersForYears founded programmers
else Right $ Shop founded programmers
mcomp :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
mcomp f g a = join $ f <$> (g a)
sayHi :: String -> IO String
sayHi greeting = do
putStrLn greeting
getLine
readM :: Read a => String -> IO a
readM = return . read
getAge :: String -> IO Int
getAge = sayHi >=> readM
askForAge :: IO Int
askForAge = getAge "Hello! How old are you? "
main :: IO ()
main = do
putStrLn "Hola!"