我正在尝试从文本文档中的信息中创建一个树。例如,在example.txt中,我们有aritmetchic表达式(3 + x) * (5 - 2)
。我想做一棵看起来像这样的树:
Node * (Node + (Leaf 3) (Leaf x)) (Node - (Leaf 5) (Leaf 2)
经过多次不成功的尝试后,我做到了这一点:
data Tree a = Empty
| Leaf a
| Node a (Tree a) (Tree a)
deriving (Show)
这是我使用的树,并且:
take name = do
elements <- readFile name
return elements
那么如何将元素放在树中呢?
答案 0 :(得分:1)
您需要将数据类型放入可以存储操作和值的树中。一种方法是创建一个表示要存储在树中的所有内容的ADT:
data Eval a
= Val a
| Var Char
| Op (a -> a -> a)
type EvalTree a = Tree (Eval a)
但这不是很理想,因为有人可以Leaf (Op (+))
,这在这里没有多大意义。相反,我建议将其结构化为
data Eval a
= Val a
| Var Char
| Op (a -> a -> a) (Eval a) (Eval a)
这本质上就是你拥有的树结构,只是限制在语法上正确。然后你可以编写一个简单的评估器
eval :: Eval a -> Data.Map.Map Char a -> Maybe a
eval vars (Val a) = Just a
eval vars (Var x) = Data.Map.lookup x vars
eval vars (Op op l r) = do
left <- eval l
right <- eval r
return $ left `op` right
这将沿着两个分支走下去,进行评估,然后最终返回计算值。你只需要为它提供一个变量图来使用值
例如,(3 + x) * (5 - 2)
将表示为Op (*) (Op (+) (Val 3) (Var 'x')) (Op (-) (Val 5) (Val 2))
。剩下的就是解析文件,这完全是另一个问题。