表达式树到字符串列表

时间:2016-05-09 15:22:36

标签: haskell expression-trees

这是我的项目,也是我上一个问题的延续。

Haskell creating new data

这是我的代码的基本部分。

data Lukasiewicz = C | I | U
    deriving (Eq,  Show, Ord)
data LExpTree a = L a
                | V [Char]
                | N (LExpTree a)
                | Q (LExpTree a)
                | S (LExpTree a)
                | K (LExpTree a)
                | A ((LExpTree a), (LExpTree a))
                | O ((LExpTree a), (LExpTree a))
                | E ((LExpTree a), (LExpTree a))
                | M ((LExpTree a), (LExpTree a))
                deriving (Show, Eq)

type Dict = [(String, Lukasiewicz)] 

type Unary a b = a -> b
type Unary2 a = a -> a
type Binary b = b -> b -> b

fold :: LExpTree a -> Unary a b -> Unary [Char] b -> Unary2 b -> Unary2 b -> Unary2 b -> Unary2 b -> Binary b -> Binary b -> Binary b -> Binary b -> b
fold (L x) l v n q s k a o e m =  l x
fold (V x) l v n q s k a o e m =  v x
fold (N x) l v n q s k a o e m =  n (fold x l v n q s k a o e m)
fold (Q x) l v n q s k a o e m =  q (fold x l v n q s k a o e m)
fold (S x) l v n q s k a o e m =  s (fold x l v n q s k a o e m)
fold (K x) l v n q s k a o e m =  k (fold x l v n q s k a o e m)
fold (A x) l v n q s k a o e m =  a (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (O x) l v n q s k a o e m =  o (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (E x) l v n q s k a o e m =  e (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (M x) l v n q s k a o e m =  m (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)

evalT :: Dict -> LExpTree Lukasiewicz -> Lukasiewicz
evalT xs x = fold x id (lk xs) negation possible sure unknown (<&>) (<|>) (<->) (-->)

最后一个函数evalT将采用DictExpression Tree并将吐出该表达式的结果,前提是用户将为{{1}的所有变量赋值在V [Char]列表中的表达式树中。

现在我需要创建一个新函数来评估表达式树。 这次输入不会有Dict。因此,输出不是结果,而是所有变量名称的列表。

我的想法是使用相同的Dict函数并忽略除fold之外的所有内容。其余的应该只是调用表达式树,不应该做任何其他事情。

但我不知道如何开始。

该功能的签名应为

V [Char]

2 个答案:

答案 0 :(得分:0)

编写varList的传统方式是这样的:

varList (V x) = [x]
varList (L _) = []
varList (N e) = varList e  -- same for all unary nodes, e.g. Q, S, K, ...
varList (A a b) = varList a ++ varList b
  -- same for the other binary nodes

所以比较:

fold (N x) l v n q s k a o e m =  n (fold x l v n q s k a o e m)
varList (N x)                  =  varList x

说服自己:

varList blah == fold blah l v n ... e m

有了这个标识,

varList x == n (fold x l v n ... e m) == n (varList x)

因此n必须是id,即身份功能。

另一个例子......确定l

varList (L x) == fold (L x) l ... e m
              == l (fold x  l ... e m)
              == l (varList x)
              == []

所以l (varList x) == []表示l必须是......?

答案 1 :(得分:0)

fold2 :: LExpTree a -> [String]
fold2  (L x) = []
fold2 (V x) = [x]
fold2 (N x) = fold2 (x)
fold2 (Q x) = fold2 (x)
fold2 (S x) = fold2 (x)
fold2 (K x) = fold2 (x)
fold2 (A x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (O x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (E x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (M x) = (fold2 (left' x)) ++ (fold2 (right' x))

varList :: LExpTree Lukasiewicz -> [String]
varList x = [y | y <- fold2 x]