【发布时间】:2015-05-25 07:49:05
【问题描述】:
我是 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 [数字 3.2,加号,减号,数字 4.2,减号,数字 5.3,加号,数字 6.3] [数量 {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 因为它是双精度的,现在我不确定这是否正确。 虽然我知道这不是详尽无遗的,因为我没有考虑到所有的可能性。 我需要帮助的是考虑负数,例如减号,加号应该返回减号,但我还需要注意顺序的工作原理,例如幂,然后是乘法/除法,然后是加法/减法。 如果调用 eval 函数,我们的讲师已经给了我们返回值: eval ((eval [Num x, op, Num y]) ++ op_next: remaining_expr)
因此,如果有人可以提供帮助,如果您明白我在说什么,那将很有帮助,哦,放轻松,请我仍在努力学习! :) 这个实验室旨在教我们模式匹配,但我仍然没有完全理解它。
我可能应该注意,我知道我应该做什么,但不知道如何正确地写它!
【问题讨论】:
-
考虑将其匹配为
(Num x : op : Num y : op_next : remaining_expr)。您可以进行更改,并且不会影响您的功能当前的工作方式。然后开始思考你可以用op_next和remaining_expr做什么。如果您需要担心操作顺序,那么请考虑您可以使用哪种模式匹配来查找这些情况。不同运营商之间有哪些不同的交互方式?确保[Num 1, Plus, Num 2, Times, Num 3]被视为1 + (2 * 3)。让那个工作,然后实施下一个规则。看看你能不能找到一个模式。 -
我投票决定将此问题作为题外话结束,因为它专门用于特定的家庭作业并且不清楚。
标签: list haskell math recursion pattern-matching