如何解决为表达式树实现变态
我试图在Haskell中实现如下表达式树:
data ExprTr a b =
Variable a
| Constant b
| Add (ExprTr a b) (ExprTr a b)
| Mul (ExprTr a b) (ExprTr a b)
deriving (Eq,Show)
我希望能够使用变态方法对其执行操作。
当前,这是我得到的功能:
cataTr f _ _ _ (Variable i) = f i
cataTr f g _ _ (Constant i) = g i
cataTr f g h i (Add e1 e2) = g (cataTr f g h i e1) (cataTr f g h i e2)
cataTr f g h i (Mul e1 e2) = h (cataTr f g h i e1) (cataTr f g h i e2)
但是,每当我尝试使用类型为ExprTr String Integer
的表达式时,都会出现编译器错误。例如,运行cataTr id id id id (Var "X")
返回以下编译器错误,而不是(Var "X")
。
Couldn't match type 'Integer' with '[Char]'
Expected type: 'ExprTr String String'
Actual type: 'ExprTr String Integer'
我不确定如何继续。此外,我希望您能提出一些建议,例如如何键入cataTr这样的函数,以便以后进行调试。
对于Haskell来说,我还很陌生,所以我想了解如何从“第一原理”着手解决这种情况,而不是使用库来为我自己生成分类。
解决方法
这是预期的行为。
您猜错了一个错字,因为您应该使用h
和i
作为函数:
cataTr f _ _ _ (Variable i) = f i
cataTr f g _ _ (Constant i) = g i
cataTr f g h i (Add e1 e2) = h (cataTr f g h i e1) (cataTr f g h i e2)
cataTr f g h i (Mul e1 e2) = i (cataTr f g h i e1) (cataTr f g h i e2)
或更优雅:
cataTr f g h i = go
where go (Variable i) = f i
go (Constant i) = g i
go (Add e1 e2) = h (go e1) (go e2)
go (Mul e1 e2) = i (go e1) (go e2)
或作为@DanielWagner suggests,带有case
表达式:
cataTr f g h i = go
where go v = case v of
Variable i -> f i
Constant i -> g i
Add e1 e2 -> h (go e1) (go e2)
Mul e1 e2 -> i (go e1) (go e2)
尽管如此,您不能使用cataTr
作为第三和第四参数来调用函数id
。这些功能需要两个参数。此外,如果a
和b
不同,则两个第一个参数不能都为id
,因为您的f
将a
映射到结果类型,并且g
将b
映射到结果类型。
例如,您可以通过以下方式传递数据构造函数以构造标识函数:
cataTr Variable Constant Add Mul (Variable "X")
因此,这将再次产生Variable "X"
,或者您可以使用Variable
将所有0
映射到const 0
,并使用id
,{{ 1}}和(+)
来评估表达式:
(*)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。