@@ -0,0 +1,138 @@
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+### Examples
39+
40+These all represent valid expressions:
41+
42+- `((1 + 2) * 3)`
43+- `1`
44+- `(((1 + 2) *3) +(1 + 1) )`
45+
46+### Minimal required combinators
47+
48+This combinator should read and return exactly one character from the input.
49+If there are no characters to read from the input, then it should fail.
50+
51+```haskell
52+anyToken :: Parser Char
53+```
54+
55+This combinator should read and return exactly one character from the input.
56+If the character does not match the given character, then it should fail.
57+
58+```haskell
59+token :: Char -> Parser ()
60+```
61+
62+This combinator should read a string of charracters. If the string does not match the given string then fail.
63+
64+```haskell
65+tokens :: String -> Parser ()
66+```
67+
68+This character reads any number of consecutive characters, which stisfy the predicate. So this can never fail.
69+
70+```haskell
71+tokensWhile :: (Char -> Bool) -> Parser String
72+```
73+
74+This character reads any number (but at least one) of consecutive characters, which stisfy the predicate. This can only fail if the first character does not satisfy the predicate.
75+
76+```haskell
77+tokensWhile1 :: (Char -> Bool) -> Parser String
78+```
79+
80+### Simple example
81+
82+A sample parser might look something like this
83+
84+```haskell
85+number :: Parser Int
86+number = do
87+ sign <- signParser
88+ digits <- digitsParser
89+ return (read (sign <> digits))
90+```
91+
92+### Control
93+
94+The proposed approach of handling control is using the `Alternative` typeclass.
95+
96+The instance for `[]` already provides the following behavior:
97+
98+`empty` represents a failure (no values).
99+
100+`<|>` represents parsing alternative. For example an expression can be either an operation or a number.
101+
102+## Complex expressions
103+
104+This is a slightly more complex version of expressions -- it includes conditional expressions
105+
106+This represents the new parts:
107+
108+```bnf
109+<expression> ::= <number> | <operation> | <conditional>
110+
111+<conditional> ::= "if " <spaces> <bool_expression> <spaces> " then " <spaces> <expression> <spaces> " else " <spaces> <expression>
112+
113+<bool_expression> ::= "(" <spaces> <expression> <spaces> <bool_operator> <spaces> <expression> <spaces> ")"
114+
115+<bool_operator> = "=" | "<" | ">" | "<=" | ">="
116+```
117+
118+### Examples
119+
120+These all represent valid expressions:
121+
122+- `if ( 1 = 2 ) then (2 + 4) else 2`
123+- `(((1 + 2) *3) +( if ( 1 = 2 ) then (2 + 4) else 2 + 1))`
124+
125+## Artifacts
126+
127+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`.
128+
129+```haskell
130+calculate :: String -> Maybe Int
131+```
132+
133+## Libraries you can use
134+
135+You can use these two libraries:
136+- `base`
137+- `mtl`
138+