qua*_*dev 8 debugging haskell pattern-matching
我已经定义了一种类型
data Expr =
Const Double
| Add Expr Expr
| Sub Expr Expr
Run Code Online (Sandbox Code Playgroud)
并将其声明为Eq类型类的实例:
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = a1+a2 == b1 + b2
Run Code Online (Sandbox Code Playgroud)
当然,表达式的评估Sub (Const 1) (Const 1) == Const 0将失败.如何在运行时调试模式匹配过程以发现它失败?我想看看Haskell如何获取参数==并遍历模式.有可能吗?
编辑:提供问题的真实答案......
我发现查看模式匹配的最简单方法是添加trace语句,如下所示:
import Debug.Trace
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = trace "Expr Eq pat 1" $ a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = trace "Expr Eq pat 2" $ a1+a2 == b1 + b2
-- catch any unmatched patterns
l == r = error $ "Expr Eq failed pattern match. \n l: " ++ show l ++ "\n r: " ++ show r
Run Code Online (Sandbox Code Playgroud)
如果您不包含最终语句来捕获任何其他不匹配的模式,您将收到运行时异常,但我发现查看您获得的数据更有用。然后通常很容易看出为什么它与之前的模式不匹配。
当然,您不想将其留在生产代码中。我只根据需要插入痕迹,然后在完成后将其删除。您还可以使用 CPP 将它们排除在生产版本之外。
我还想说,我认为模式匹配是解决这个问题的错误方法。您最终会遇到模式数量的组合爆炸,这很快就会变得难以管理。例如,如果您想创建一个Float实例Expr,则需要几个更原始的构造函数。
相反,您可能有一个解释器函数interpret :: Expr -> Double,或者至少可以编写一个。然后你可以定义
instance Eq Expr where
l == r = interpret l == interpret r
Run Code Online (Sandbox Code Playgroud)
通过模式匹配,您实际上是在实例中重写您的解释函数Eq。如果你想创建一个Ord实例,你最终将再次重写解释函数。
| 归档时间: |
|
| 查看次数: |
1041 次 |
| 最近记录: |