[英]beginner implementation of Catamorphism for non binary trees versus the Composite Design Pattern
[英]Implementing a catamorphism for Expression Trees
我正在尝试在 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)
我希望能够使用 catamorphism 对其进行操作。
目前,这是我得到的功能:
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
类型的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 相当陌生,因此我想了解如何从“第一原则”来处理这种情况,而不是使用库来为自己生成 catamorphism。
这是预期的行为。
我猜您在问题中打错了字,因为您应该使用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 建议的那样,使用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)
但是,您不能使用id
作为第三个和第四个参数调用cataTr
函数。 这些函数需要两个参数。 此外,如果a
和b
不同,则两个第一个参数不能都是id
,因为您的f
将a
映射到结果类型,而g
将 a b
映射到结果类型。
例如,您可以传递数据构造函数来构造一个标识函数:
cataTr Variable Constant Add Mul (Variable "X")
因此,这将产生Variable "X"
一次,或可以例如所有映射Variable
s到0
与const 0
,并且使用id
, (+)
和(*)
来评估的表达式:
cataTr (const 0) id (+) (*) (Variable "X")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.