温馨提示:本文翻译自stackoverflow.com,查看原文请点击:abstract syntax tree - traversal of boolean AST in Haskell
abstract-syntax-tree haskell

abstract syntax tree - 在Haskell中遍历布尔AST

发布于 2020-04-10 11:35:20

我在完成要创建使用广义折叠函数评估布尔AST的函数的任务时遇到了麻烦。我将向您展示一些示例进行说明。

首先,给出一个我想要的示例,但对于一个将整数相加的AST:

data Expr = Val Int | Add Expr Expr deriving Show

folde :: (Int -> a) -> (a -> a -> a) -> Expr -> a
folde f g (Val x)   = f x
folde f g (Add x y) = g (folde f g x) (folde f g y)

eval :: Expr -> Int
eval expr = folde (\x -> x) (\x y -> x + y) expr

这很好。

现在是布尔AST和折叠功能:

data Bexp = T | F | And Bexp Bexp | Or Bexp Bexp deriving (Ord, Eq)

foldb :: a -> a -> (a -> a -> a) -> (a -> a -> a) -> Bexp -> a
foldb t f a o T         = t
foldb t f a o F         = f 
foldb t f a o (And x y) = a (foldb t f a o x) (foldb t f a o y)  
foldb t f a o (Or x y)  = o (foldb t f a o x) (foldb t f a o y)

我遇到的麻烦是,创建了一个与上述简单AST的eval函数相同的函数,也就是说,使用带有一些lambda的foldb函数来评估Bexp表达式是T还是F

我不明白为什么这个功能不起作用:

evb :: Bexp -> Bool
evb bexp = foldb (\_ -> True) (\_ -> False) (\x y -> x == T && y == T) (\x y -> x == T || y == T) bexp

由于类型错误,GHCi甚至不想编译它。

提前致谢。

查看更多

提问者
clickedok
被浏览
124
chi 2020-02-02 16:36

如果想在最后使用foldba Bool,则需要选择a = Bool其类型。所以,我们现在正在使用

foldb :: Bool 
      -> Bool
      -> (Bool -> Bool -> Bool)
      -> (Bool -> Bool -> Bool)
      -> Bexp
      -> Bool

因此,这foldb (\_->True) (\_->False) ...是错误的,因为前两个参数必须是布尔值,而不是函数。我们需要类似的东西foldb True False ...接下来的两个参数必须是布尔型二进制运算符,例如\x y -> x && y,可以(&&)简写为。

我们终于得到:

evb :: Bexp -> Bool
evb bexp = foldb True False (&&) (||)