【发布时间】:2014-05-10 06:14:03
【问题描述】:
我们的作业得到以下数据结构:
-- Question 2: Expression tree.
data Expr
= Lit Float
| Add Expr Expr
| Sub Expr Expr
| Mul Expr Expr
| Div Expr Expr
| X
它代表一个浮点值,两个子树的add/sub/mul/div,或者一个代表未知变量的X。我们必须编写一个可以漂亮地打印树的方法。这是我目前所拥有的:
draw :: Expr -> Int -> String
draw (Lit f) _ = show f
draw (X) _ = "X"
draw (Add a b) lvl = indent lvl ++ "(+) ---" ++ draw a (lvl+1) ++ "\n" ++ indent lvl ++ "|\n" ++ indent lvl ++ "---" ++ draw b (lvl+1)
draw (Sub a b) lvl = indent lvl ++ "(-) ---" ++ draw a (lvl+1) ++ "\n" ++ indent lvl ++ "|\n" ++ indent lvl ++ "---" ++ draw b (lvl+1)
draw (Mul a b) lvl = indent lvl ++ "(*) ---" ++ draw a (lvl+1) ++ "\n" ++ indent lvl ++ "|\n" ++ indent lvl ++ "---" ++ draw b (lvl+1)
draw (Div a b) lvl = indent lvl ++ "(/) ---" ++ draw a (lvl+1) ++ "\n" ++ indent lvl ++ "|\n" ++ indent lvl ++ "---" ++ draw b (lvl+1)
indent :: Int -> [Char]
indent 0 = []
indent n = "\t"++indent (n-1)
这适用于简单的树:
myE2 :: Expr
myE2 = Add (Lit 4) (Sub (Lit 4) (Lit 2))
打印为:
*Main> putStr(draw myE2 0)
(+) ---4.0
|
--- (-) ---4.0
|
---2.0
这是我想要的,但是,更复杂的树,例如:
myExpr :: Expr
myExpr = (Add (Add (Sub (Mul (Lit 4) (X)) (Lit 1)) (Lit 4)) (Lit 6))
打印为:
*Main> putStr(draw myExpr 0)
(+) --- (+) --- (-) --- (*) ---4.0
|
---X
|
---1.0
|
---4.0
|
---6.0
谁能就我如何解决这个问题提供建议?
【问题讨论】:
-
一个简单的选择:使用其
unfoldTree函数将您的Expr转换为标准Data.Tree,然后调用drawTree函数。 -
这是家庭作业;我们不允许使用它。
-
如果它不需要以这种格式进行漂亮打印,您可能会喜欢a previous similar question 对漂亮打印表单的最小括号。
标签: haskell tree pretty-print