So we have following Data Types:
data Expr = Num Double | Add Expr Expr | Var Char deriving Show
and
type Env = [(Char, Double)]
Further More we have these two functions:
evalDo :: Env -> Expr -> Maybe Double
evalDo _ (Num a) = return a
evalDo e (Var c) = getvar e c
evalDo e (Add a b) = do
a' <- evalDo e a
b' <- evalDo e b
Just (a'+b')
and
getvar :: Env -> Char -> Maybe Double
getvar [] c = Nothing
getvar ((x,y):es) c
| c == x = Just y
|otherwise = getvar es c
So if we would run the following Code:
evalDo [('x', 2)] (Add (Num 5) (Var 'x')), we would receive:Just 7.0.
Whereas evalDo [('x', 2)] (Add (Num 5) (Var 'y')) evaluates to Nothing.
From what I understand when running the former code, our function matches the evalDo e (Var c) = getvar e c line. From there it calls getvar e c which results in Just 2. Then we go back to our original second call, which is
(Add (Num 5) (Var 'x'))
. Now the Var 'x' is resolved into Just 2. So finally the evalDo e (Add a b) = do... function-line matches and we get Just7.0.
Obviously there is a huge major flaw to my explanation, since we try to "Add" Num 5 and Just 2 and by our definition its not possible. Yet the function seems to work flawelessly somehow but I just can't figure it out.