2016-05-16 27 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