List Haskell,求解基本方程的函数

List Haskell,求解基本方程的函数,list,haskell,math,recursion,pattern-matching,List,Haskell,Math,Recursion,Pattern Matching,我是haskell的新手,因为我在大学就开始了, 我以前在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 e

我是haskell的新手,因为我在大学就开始了, 我以前在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中输入时,该函数应该可以解这个方程:

求值[数值3.2,加,减,数值4.2,减,数值5.3,加,数值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,加上Num 4.2]中输入这个 它返回7.3000000000001,因为它是双精度的,现在我不确定这是否正确。 虽然我知道这不是详尽无遗的,因为我没有考虑所有的可能性。 我需要帮助的是考虑负数,比如负数,加号应该返回负数,但我还需要注意顺序是如何工作的,比如幂,然后是乘法/除法,然后是加法/减法。 如果调用eval函数,我们的讲师给了我们返回值: eval((eval[Num x,op,Num y])++op\u next:剩余的表达式)

所以,如果有人能帮上忙,如果你明白我说的话,那会很有帮助的,哦,别着急,我还在努力学习呢!:) 这个实验室的目的是教我们模式匹配,但我仍然不完全理解它


我可能应该注意到,我知道我应该做什么,但只是不知道如何正确地写它

噢,嗨,coursemate,是的,这周的实验室也让我发疯了

我在9个案例中这样做了(我认为这很糟糕,我需要找到一个更好的方法,尽管效果很好)

我所做的是建立覆盖所有可能输入的模式

  • px:Num x:op:py:Num y:opn:r
  • px:Num x:op:Num y:opn:r
  • 数量x:op:py:Num y:opn:r
  • 数量x:op:Num y:opn:r
  • 数量x:op:numy:[]
  • Num x:op:py:Num y:[]
  • px:Num x:op:Num y:[]
  • px:Num x:op:py:Num y:[]
  • _
  • 其中px和py是数字前缀(加/减)

    在案例2~3中,他们将再次调用eval,该过程将处理案例1,与案例5~7相同,他们将处理案例8。所以案例1和案例8是进行实际计算的案例

    案例1是处理绑定幂函数(计算操作员优先级)

    在第8种情况下,进行最终计算(注意零除法),可以设置where子句,如转换负数:

    tx = (if px == Minus then -1 else 1) * x
    ty = (if py == Minus then -1 else 1) * y
    

    如果你想要破坏者,这里有一个链接:

    考虑将其匹配为
    (Num x:op:Num y:op\u next:remaining\u expr)
    。您可以进行更改,但不会影响当前函数的工作方式。然后开始思考如何使用
    op\u next
    剩余的expr
    。如果您需要担心操作的顺序,那么考虑您可以做什么样的模式匹配来找到这些情况。不同运营商之间的不同互动是什么?确保将
    [Num 1,Plus,Num 2,Times,Num 3]
    视为
    1+(2*3)
    。让这一条起作用,然后实施下一条规则。看看你是否能找到一个模式。看,我投票结束这个问题,因为它是专门针对一个特定的家庭作业和不明确的主题。嘿,谢谢你,伙计,这是非常有意义的,现在我知道我明白了,它只是没有通过我的头。但我肯定会用我自己的方式去做,但我非常感谢你的帮助!