forked from belyaev-mikhail/fp-practice-2019
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTask6.hs
80 lines (66 loc) · 1.77 KB
/
Task6.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
module Task6 where
{-
В этом файле приведён код, написанный (совместными усилиями) на лекции
Модифицируйте представленный тут парсер таким образом, чтобы он поддерживал унарные операции
(отрицание и факториал), а также числа с плавающей точкой
-}
import Text.Parsec hiding(digit)
import Data.Functor
type Parser a = Parsec String () a
digit :: Parser Char
digit = oneOf ['0'..'9']
number :: Parser Integer
number = read <$> many1 digit
applyMany :: a -> [a -> a] -> a
applyMany x [] = x
applyMany x (h:t) = applyMany (h x) t
div_ :: Parser (Integer -> Integer -> Integer)
div_ = do
char '/'
return div
star :: Parser (Integer -> Integer -> Integer)
star = do
char '*'
return (*)
plus :: Parser (Integer -> Integer -> Integer)
plus = do
char '+'
return (+)
minus :: Parser (Integer -> Integer -> Integer)
minus = do
char '-'
return (-)
multiplication :: Parser Integer
multiplication = do
spaces
lhv <- atom
spaces
t <- many tail
return $ applyMany lhv t
where tail =
do
f <- star <|> div_
spaces
rhv <- atom
spaces
return (`f` rhv)
addition :: Parser Integer
addition = do
spaces
lhv <- multiplication
spaces
t <- many tail
return $ applyMany lhv t
where tail =
do
f <- plus <|> minus
spaces
rhv <- multiplication
spaces
return (`f` rhv)
atom :: Parser Integer
atom = number <|> do
char '('
res <- addition
char ')'
return res