@@ -0,0 +1,155 @@
1+# Mathematical expression interpreter
2+
3+Your task is to:
4+1. Write monadic parsing combinators
5+2. Define a structure to represent a parsed mathematical expression in Haskell
6+3. Write a parser, which parses a string into the structure
7+4. Write an interpreter for the structure, which performs the calculation and returns the result.
8+
9+**NOTE: the parser and interpreter should be independent.**
10+
11+You will have to handle division by zero errors.
12+
13+## The basic expression
14+
15+### Formal Definition
16+
17+Note that the expressions can be nested arbitrarily deeply.
18+
19+Also note, that a number can only be an integer.
20+
21+The `/` operator is integer division truncated towards negative infinity (`div` in Haskell).
22+
23+```bnf
24+<expression> ::= <number> | <operation>
25+
26+<number> ::= "-" <digits> | <digits>
27+
28+<digits> ::= <digit> | <digit> <digits>
29+<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
30+
31+<operation> ::= "(" <spaces> <expression> <spaces> <operator> <spaces> <expression> <spaces> ")"
32+
33+<operator> ::= "+" | "-" | "*" | "/"
34+
35+<spaces> ::= "" | " " <spaces>
36+```
37+
38+### Exmaples
39+
40+These all represent valid expressions:
41+
42+- `((1 + 2) * 3)`
43+- `1`
44+- `(((1 + 2) *3) +(1 + 1) )`
45+
46+## The proposed approach
47+
48+The proposed approach is to use the following monad for parsing
49+
50+```haskell
51+type Parser a = StateT String [] a
52+```
53+
54+`StateT String` -- the state contains the String being currently parsed.
55+
56+`[]` -- the base monad should be a list. This will provide us with the context of trying different combinations of alternatives, and will also provide a failure context (the empty list).
57+
58+The result of the parser would be a (possible infinity) list of possible parsed values. You should take the first one.
59+
60+You can provide a different definition of the `Parser` monad, but you can not use a monad, which was intended for parsing.
61+
62+### Minimal required combinators
63+
64+This combinator should read and return exactly one character from the input.
65+If there are no characters to read from the input, then it should fail.
66+
67+```haskell
68+anyToken :: Parser Char
69+```
70+
71+```haskell
72+token :: Char -> Parser ()
73+```
74+
75+```haskell
76+tokens :: String -> Parser ()
77+```
78+
79+```haskell
80+tokensWhile :: (Char -> Bool) -> Parser String
81+```
82+
83+```haskell
84+tokensWhile1 :: (Char -> Bool) -> Parser String
85+```
86+
87+### Simple example
88+
89+A sample parser might look something like this
90+
91+```haskell
92+number :: Parser Int
93+number = do
94+ sign <- signParser
95+ digits <- digitsParser
96+ return (read (sign <> digits))
97+```
98+
99+### Control
100+
101+The proposed approach of handling control is using the `Alternative` typeclass.
102+
103+The instance for `[]` already provides the following behavior:
104+
105+`empty` represents a failure (no values).
106+
107+`<|>` represents parsing alternative. For example an expression can be either an operation or a number.
108+
109+## Complex expressions
110+
111+This is a slightly more complex version of expressions -- it includes conditional expressions
112+
113+This represents the new parts:
114+
115+```bnf
116+<expression> ::= <number> | <operation> | <conditional>
117+
118+<conditional> ::= "if " <spaces> <bool_expression> <spaces> " then " <spaces> <expression> <spaces> " else " <spaces> <expression>
119+
120+<bool_expression> ::= "(" <spaces> <expression> <spaces> <bool_operator> <spaces> <expression> <spaces> ")"
121+
122+<bool_operator> = "=" | "<" | ">" | "<=" | ">="
123+```
124+
125+### Examples
126+
127+These all represent valid expressions:
128+
129+- `if ( 1 = 2 ) then (2 + 4) else 2`
130+- `(((1 + 2) *3) +( if ( 1 = 2 ) then (2 + 4) else 2 + 1) )`
131+
132+## Artifacts
133+
134+You should export the `calculate` function, which should parse the given string and return the computed result. If any of the steps involved fail (couldn't parse the string or there was a divide by zero error), you should return `Nothing`.
135+
136+```haskell
137+calculate :: String -> Maybe Int
138+```
139+
140+## Libraries you can use
141+
142+You can use these two libraries:
143+- `base`
144+- `mtl`
145+
146+## Grading
147+
148+| Requirement | Score |
149+| -------------------------------------------------------- | ----- |
150+| Definition of the structure, representing the expression | 1 |
151+| Definition of the minimal monadic parser combinators | 2 |
152+| Definition of the expression parser | 2 |
153+| Definition of the expression interpreter | 2 |
154+| All of the above for complex expressions | 2 |
155+| Proper decomposition of functionality and coding style | 1 |