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
布尔数据类型合并到总方程中呢?
答案 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
标志打开警告也是一个好主意,因为警告会发现一些潜在的错误。