forked from karan/Projects
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWordNumbers.hs
64 lines (49 loc) · 1.7 KB
/
WordNumbers.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
module WordNumbers where
-- A beautiful approach from Chung-chieh Shan
-- (http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers1/)
import Prelude hiding ((+), (*), sum, product)
import qualified Prelude as P
import Control.Monad
infixl 6 +
infixl 7 *
-- | Define Monoids clearly as the commutative part of a
-- (semi)(near)ring
class Monoid a where
zero :: a
(+) :: a -> a -> a
-- | The Free construction
instance Monoid [a] where
zero = []
(+) = (++)
sum :: (Monoid a) => [a] -> a
sum = foldr (+) zero
-- | Append another non-commutative monoid to get a seminearring.
--
-- A seminearring is a 'Monoid' with an additional associative
-- operation '(*)' and its identity element 'one' satisfying
-- distributivity on one side only.
--
-- (x+y) * z = x*z + y*z
class (Monoid a) => Seminearring a where
one :: a
(*) :: a -> a -> a
product :: (Seminearring a) => [a] -> a
product = foldr (*) one
instance Seminearring [[a]] where
one = [[]]
xss * yss = [ xs ++ ys | xs <- xss, ys <- yss ]
string :: String -> [String]
string = product . map (\x -> [[x]])
strings :: String -> [String]
strings = sum . map string . words
ten1, ten2, ten3, ten6, ten9 :: [String]
ten1 = strings "one two three four five six seven eight nine"
ten2 = ten1 + strings "ten eleven twelve"
+ (strings "thir four" + prefixes) * string "teen"
+ (strings "twen thir for" + prefixes) * string "ty" * (one + ten1)
where prefixes = strings "fif six seven eigh nine"
ten3 = ten2 + ten1 * string "hundred" * (one + ten2)
ten6 = ten3 + ten3 * string "thousand" * (one + ten3)
ten9 = ten6 + ten3 * string "million" * (one + ten6)
main :: IO ()
main = forever $ readLn >>= print . (("zero":ten9) !!)