我是haskell的新手并且已经开始了因为我在UNI做了这件事, 我以前有过C,C#和HTML,CSS的经验。我们有一个实验室 我们获得代码的那一周:
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))
所以现在我们打算实现一个名为eval的自己的函数,它应该在ghci中输入时解决这个等式:
eval [Num 3.2,Plus,Minus,Num 4.2,Minus,Num 5.3,Plus,Num 6.3] [Num {number = 0.0}]
所以在这一点上我已经使用了模式匹配(判断我理解它)并且做到了这一点:
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 "......"
现在如果我输入ghci:eval [Num 3.1,Plus,Num 4.2] 它返回7.300000000001,因为它是一个双,现在我不确定这是否正确。 虽然我知道这不是详尽无遗的,因为我没有照顾所有的可能性。 我需要帮助的是考虑负数,例如Minus,Plus应该返回减号,但我还需要注意顺序如何工作,例如Powers,然后乘法/除法然后加法/减法。 如果调用eval函数,我们的讲师给了我们返回值: eval((eval [Num x,op,Num y])++ op_next:remaining_expr)
所以,如果有人可以提供帮助,如果你明白我说的话会有所帮助,哦,轻松一点,我还在努力学习! :) 本实验旨在教我们模式匹配,但我仍然不能完全理解它。
我可能应该注意到,我知道自己应该做什么,但却不知道如何正确地写它!
答案 0 :(得分:-2)
哦,当然,是的,本周的实验室也让我发疯了。
我在9个案例中做到了这一点(我认为这很糟糕,我需要找到一个更好的方法,但它工作得很好)。
我所做的是设置涵盖所有可能输入的模式
其中px和py是数字前缀(加号/减号)
在情况2~3中,他们再次调用eval,处理到情况1,与情况5~7相同,他们将处理到情况8。所以情况1& 8是进行实际计算的情况。
案例1是您处理binding_power函数(计算运算符优先级)的地方;
案例8是您进行最终计算的地方(注意零分割),您可以设置一个where子句,比如翻译负数:
tx = (if px == Minus then -1 else 1) * x
ty = (if py == Minus then -1 else 1) * y
如果您想要剧透,请点击以下链接:http://pastebin.com/Vq8PC6Z3