haskell,数据树函数,字符串输出?

时间:2016-05-16 12:42:35

标签: haskell types tree pattern-matching

我创建了一个数据类型树和一个数据类型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))"

1 个答案:

答案 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