【问题标题】:Evaluating nested boolean data type评估嵌套布尔数据类型
【发布时间】:2019-04-24 17:33:36
【问题描述】:

If 数据构造函数 (If BoolType Expr Expr) 应该计算布尔表达式(第一个参数),如果为真则返回第二个参数的值,或者返回第三个参数。我可以构造表达式 Expr 的评估,但我不明白如何合并嵌套表达式 BoolType 以评估表达式。有点太曲折了,我无法理解它。

这里有两种数据类型:

data Expr = Val Int
          | Add Expr Expr
          | Sub Expr Expr
          | Mul Expr Expr
          | Div Expr Expr
          | If BoolType Expr Expr

data BoolType = Lit Bool
          | Or BoolType BoolType
          | EqualTo Expr Expr
          | LessThan Expr Expr

我写了一个评估类型的表达式:

eval :: BoolType -> Bool
eval (Lit n)      = n
eval (Or e1 e2)       = eval e1 || eval e2
eval (EqualTo e1 e2)  = num e1 == num e2
eval (LessThan e1 e2) = num e1 < num e2

num :: Expr -> Int
num (Val n)          = n
num (Add e1 e2)      = num e1 + num e2
num (Sub e1 e2)      = num e1 - num e2
num (Mul e1 e2)      = num e1 * num e2
num (Div e1 e2)      = num e1 `div` num e2

它应该计算出任何正规方程,但我如何将 If 布尔数据类型合并到总方程中?

【问题讨论】:

  • 只需向value 添加另一个分支来处理If 的情况。您是否遇到过任何具体问题?还有,你为什么要复制numvalue之间的代码?
  • 技术上是两段代码。合并If 语句的语法是什么?我的困惑在于实际的语法。我不确定如何添加If
  • 您昨天是否针对您的类似问题实施了@melpomene 的出色answer?如果你已经这样做了,处理If 的情况也应该是微不足道的。
  • 他们做得很棒。我的困惑是如何处理 If 的情况,我认为必须以不同的方式处理,但我想多了。

标签: haskell


【解决方案1】:

求值函数目前的模式匹配不完整:

*Q55835635> :l 55835635.hs
[1 of 1] Compiling Q55835635        ( 55835635.hs, interpreted )

55835635.hs:22:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `num': Patterns not matched: (If _ _ _)
   |
22 | num (Val n)          = n
   | ^^^^^^^^^^^^^^^^^^^^^^^^^...
Ok, one module loaded.

只需将缺少的模式添加到num

num :: Expr -> Int
num (Val n)          = n
num (Add e1 e2)      = num e1 + num e2
num (Sub e1 e2)      = num e1 - num e2
num (Mul e1 e2)      = num e1 * num e2
num (Div e1 e2)      = num e1 `div` num e2
num (If b e1 e2)     = if (eval b) then num e1 else num e2

您现在可以计算表达式,包括带有 If 表达式的表达式:

*Q55835635> num $ Add (Val 40) (If (Lit True) (Val 2) (Val 0))
42

其余的功能都不需要了。

【讨论】:

  • 我觉得提取出重复的num call:num (If b x y) = num $ if eval b then x else y会更好一点
【解决方案2】:

你可以继续你的方法,添加一个合适的方程:

value (If cond e1 e2) = ifHelper (eval cond) (value e1) (value e2)

然后,你需要定义你的助手:

ifHelper :: Bool -> Maybe Int -> Maybe Int -> Maybe Int
ifHelper True  m1 m2 = ...
ifHelper False m1 m2 = ...

顺便说一句,通常建议在开始编写函数本身之前定义任何函数的类型。这有助于程序员(他们可以推断出参数的类型)和编译器(如果出现问题,编译器可以产生更好的错误消息)。

使用-Wall 标志打开警告也是一个好主意,因为警告可以发现几个潜在的错误。

【讨论】:

    猜你喜欢
    • 2019-07-22
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多