I'm new to haskell and have started it because I'm doing it at UNI, I've had previous experience in C, C# and HTML, CSS. We had a lab this week where we were given the code :
data Token = Plus | Minus | Times | Divided_By | Power | Num {number :: Double}
deriving (Show, Eq)
type Expression = [Token]
tokenizer :: String -> Expression
tokenizer expression_as_string = case expression_as_string of
"" -> []
c: cs -> case c of
'+' -> Plus : tokenizer cs
'-' -> Minus : tokenizer cs
'*' -> Times : tokenizer cs
'/' -> Divided_By : tokenizer cs
'^' -> Power : tokenizer cs
_ | c `elem` ['0' .. '9'] -> case reads expression_as_string of
[(value, rest)] -> Num value : tokenizer rest
_ -> error "Could not read number"
| c `elem` [' ', '\t'] -> tokenizer cs
| otherwise -> error "Unknown Symbol"
expression_to_string :: Expression -> String
expression_to_string expr = case expr of
[] -> ""
e: es -> case e of
Plus -> " + " ++ expression_to_string es
Minus -> " - " ++ expression_to_string es
Times -> " * " ++ expression_to_string es
Divided_By -> " / " ++ expression_to_string es
Power -> " ^ " ++ expression_to_string es
Num x -> (show x) ++ expression_to_string es
eval_string_expression :: String -> String
eval_string_expression s = expression_to_string (eval (tokenizer s))
So now we are meant to implement out own function called eval which should solve this equation, when typed in ghci:
eval [Num 3.2, Plus, Minus, Num 4.2, Minus, Num 5.3, Plus, Num 6.3] [Num {number = 0.0}]
So at this point i've used pattern matching (judging that i understand it) and got this far:
eval :: Expression -> Expression
eval list = case list of
[] -> []
[Num x, op, Num y] -> case op of
Plus -> [Num (x + y)]
Minus -> [Num (x - y)]
Times -> [Num (x * y)]
Divided_By -> [Num (x / y)]
Power -> [Num (x ** y)]
_ -> error "......"
Now if i type this into ghci: eval[Num 3.1, Plus, Num 4.2] it returns 7.300000000001 because it is a double, now im not sure if this is correct. Though i do know that this is non-exhaustive because i havent taken care of all the possibilities. What i need help with is taking a negative number into consideration such as Minus, Plus which should return a Minus but I also need to take note of how order works, such as Powers, then Multiplication/Division then Addition/Subtraction. Our lecturer has given us the return value if the eval function is called: eval ((eval [Num x, op, Num y]) ++ op_next: remaining_expr)
So if anyone can help, if you understand what i am saying it would be helpful, ohh and go easy please im still trying to learn! :) This lab is meant to teach us pattern matching but i still don't fully understand it.
I probably should note that I know what I am meant to do but just not how to write it correctly!
(Num x : op : Num y : op_next : remaining_expr)
instead. You can make that change and it won't affect how your function currently works. Then start thinking about what you can do withop_next
andremaining_expr
. If you need to worry about order of operations then think about what kind of pattern match you could do to find those cases. What are the different interactions between the different operators? Make sure that[Num 1, Plus, Num 2, Times, Num 3]
is treated as1 + (2 * 3)
. Get that one working, then implement the next rule. See if you can find a pattern. – bheklilr