2016-05-16 28 views
0

我犯了一个数据类型树和数据类型的作品,现在我想提出,将产生与操作字符串的函数:haskell,数据树函数,字符串输出?

我所有的代码首先:

data Op = Add | Sub | Mult | Div 
    deriving(Eq,Show) 
data Tree a b = Leaf a | Node (Tree a b) b (Tree a b) 
    deriving(Eq,Show) 

我的树

tree = Node (Node (Node (Leaf 20) Add (Leaf 20)) Sub (Leaf 2)) Mult (Node (Leaf 33) Div (Leaf 3)) 

--     Node _ Mult _ 
--     /   \ 
--     /   \ 
--     /    \ 
--    /    \ 
--    /     \ 
--    /     \ 
--    Node _ Sub _    Node _ Div _ 
--    / \     / \ 
--    /  \     /  \ 
--    / Leaf 2   Leaf 33 Leaf 3 
--   /   
--   /   
--   Node _ Add _     
--   /  \ 
--   /  \ 
--   /   \ 
--   Leaf 20  Leaf 30 

在结束时,输出应该是这样的字符串"(((20+30)-2)*(33 div 3))”

+1

听起来有点像一个家庭作业,你尝试过什么?什么工作,什么没有?尝试通过手动将小型树(1叶,1节点和2片叶......)转换为字符串来解决您的问题。看看你是否不能用递归定义一个为所有树做这个的函数。 – jakubdaniel

回答

1
treeToStr :: (Show a, Show b) => Tree a b -> String 
treeToStr (Leaf a) = show a 
treeToStr (Node a n b) = "(" ++ treeToStr a ++ show n ++ treeToStr b ++ ")" 

您只需要提供操作符转换来输出符号而不是隐式实现Show。为此,您要么手动实例化Show,要么Op要么引入一个新类,要么专门化您的treeToStr

data Op = Add | Sub | Mult | Div 
    deriving Eq 

-- Be careful about giving non-standard implementations of classes like show, in Haskell there are always laws and rules to follow: Show should output what Read would accept for example. 
instance Show Op where 
    show Add = ... 
    ... 

data Op = ... deriving Eq 
data Tree = ... deriving Eq 

class Stringifiable c where 
    toStr :: c -> String 

instance Stringifiable Op where 
    toStr Add = ... 

instance (Show a, Stringifiable b) => Stringifiable (Tree a b) where 
    toStr (Leaf a) = show a 
    toStr (Node a n b) = "(" ++ toStr a ++ toStr n ++ toStr b ++ ")" 

-- You can then stringify your tree: 
toStr tree 

或者干脆

opTreeToStr :: Show a => Tree a Op -> String 
opTreeToStr (Leaf a) = show a 
opTreeToStr (Node a n b) = "(" ++ toStr a ++ opToStr n ++ toStr b ++ ")" 

opToStr :: Op -> String 
opToStr Add = "+" 
... 

-- Stringify tree, assuming it has the correct type Tree a Op: 
opTreeToStr tree