【问题标题】:Comparison of custom data type with parameters自定义数据类型与参数的比较
【发布时间】:2016-05-08 12:10:38
【问题描述】:

我正在学习 Haskell 并尝试实现这个程序。我有一个自定义数据类型

data CalculatorInput 
    = Exit 
    | Error String 
    | Operator (Int -> Int -> Int)
    | Number Int

然后我有一个方法getInput,它返回这个类型的值。

现在我很困惑如何调度这种类型的值。我有方法

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO ()
simpleCalculator ans op =  do
    input <- getInput   -- here i got the type as result
    if input == Exit then return()
    else if input == Number x then ans = ans op x; print ans
    else simpleCalculator ans op

我想知道输入是否是Number x

我也尝试使用case

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO ()
simpleCalculator ans op =  do
    input <- getInput   -- here i got the type as result
    --case input of
    --  Exit -> return ()
    --  Error x -> print x
    --  Number n -> ans = ans op x; print ans  -- getting error here, multiple statement not possible
    --  _ -> simpleCalculator ans op

我也尝试创建Eq 的实例

instance Eq CalculatorInput where
    (==) Exit Exit = True
    (==) (Number x) (Number y) = x == y
    (==) _ _ = False 

如何比较自定义数据类型与参数或在case 分支中有多个语句?

【问题讨论】:

  • @MathematicalOrchid。它没有用。我试过。我还注意到它在 let ans = op ans n 上进入 inifnite 循环
  • @WaqarAhmedm let ans = op ans n -- 这递归地根据自身定义ans。您需要使用新名称,在这种情况下我们经常使用素数'let ans' = op ans n
  • @luqui..我明白了..谢谢。还有一个问题,为什么不从 simpleCalculator 方法返回值是好的?

标签: haskell pattern-matching algebraic-data-types do-notation


【解决方案1】:

您的非工作代码几乎走在了正确的轨道上:

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO ()
simpleCalculator ans op =  do
    input <- getInput   -- here i got the type as result
    case input of
      Exit -> return ()
      Error x -> print x
      Number n -> ans = ans op x; print ans
      _ -> simpleCalculator ans op

您可以嵌套do 符号,以便您编写以下正确的程序:

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO ()
simpleCalculator ans op =  do
    input <- getInput   -- here i got the type as result
    case input of
      Exit -> return ()
      Error x -> print x
      Number n -> do
        let theAns = ans op x
        print theAns
      _ -> simpleCalculator ans op

至于Eq实例,你可以使用derivation让编译器为你完成工作,即写

data CalculatorInput 
    = Exit 
    | Error String 
    | Operator (Int -> Int -> Int)
    | Number Int
    deriving Eq

【讨论】:

  • 嗨仙人掌,我昨天尝试了同样的逻辑,它奏效了。但我很困惑,如果我使用 ans = ans op x。它进入无限循环。你能告诉我为什么会这样吗?
  • 那是因为如果你做let ans = ans op x,右边的ans指的是同一个ans被定义。
  • 谢谢你,我明白了...还有一个问题,为什么不从诸如在这种情况下的 simpleCalculator 方法之类的方法中返回值是好的?
【解决方案2】:

使用case

simpleCalculator ans op =  do
    input <- getInput   -- here i got the type as result
    case input of
        Exit -> return ()
        Number x -> print $ans `op` x
        _ -> simpleCalculator ans op

您不能为CalculatorInput 派生Eq,因为函数不是Eq 的实例。

【讨论】:

  • 我已经在这样做了。如何在switch case中执行多条语句?
  • 请看我的代码。在 Haskell 中,您不执行语句。它们是声明的,而不是执行的。
猜你喜欢
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 1970-01-01
  • 2020-09-28
  • 2019-09-09
相关资源
最近更新 更多