我创建了一个数据类型树和一个数据类型Op,现在我想创建一个函数来生成一个带有操作的字符串:
首先我的代码:
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))"
答案 0 :(得分: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