繁体   English   中英

为表达式树实现 catamorphism

[英]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。

这是预期的行为

我猜您在问题中打错了字,因为您应该使用hi作为函数:

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函数。 这些函数需要两个参数。 此外,如果ab不同,则两个第一个参数不能都是id ,因为您的fa映射到结果类型,而g将 a b映射到结果类型。

例如,您可以传递数据构造函数来构造一个标识函数:

cataTr Variable Constant Add Mul (Variable "X")

因此,这将产生Variable "X"一次,或可以例如所有映射Variable s到0const 0 ,并且使用id(+)(*)来评估的表达式:

cataTr (const 0) id (+) (*) (Variable "X")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM