将文件中的元素加载到haskell中的树中

时间:2014-02-07 17:35:08

标签: parsing haskell tree

我正在尝试从文本文档中的信息中创建一个树。例如,在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

那么如何将元素放在树中呢?

1 个答案:

答案 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))。剩下的就是解析文件,这完全是另一个问题。