评估嵌套的布尔数据类型

时间:2019-04-24 17:33:37

标签: haskell

If数据构造函数(If BoolType Expr Expr)应该计算布尔表达式(第一个参数),如果第二个参数为true,则返回第二个参数的值,或者返回第三个参数。我可以构造表达式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布尔数据类型合并到总方程中呢?

2 个答案:

答案 0 :(得分:2)

评估程序功能当前具有不完整的模式匹配:

*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

其余功能不是必需的。

答案 1 :(得分:0)

您可以继续您的方法,添加一个合适的等式:

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标志打开警告也是一个好主意,因为警告会发现一些潜在的错误。