3
最近,我試圖解決Haskell 99問題,第66(緊湊地佈局一棵樹)。我成功了,但被這裏的解決方案搞糊塗了(http://www.haskell.org/haskellwiki/99_questions/Solutions/66)。Haskell佈局樹
layout :: Tree a -> Tree (a, Pos)
layout t = t'
where (l, t', r) = layoutAux x1 1 t
x1 = maximum l + 1
layoutAux :: Int -> Int -> Tree a -> ([Int], Tree (a, Pos), [Int])
layoutAux x y Empty = ([], Empty, [])
layoutAux x y (Branch a l r) = (ll', Branch (a, (x,y)) l' r', rr')
where (ll, l', lr) = layoutAux (x-sep) (y+1) l
(rl, r', rr) = layoutAux (x+sep) (y+1) r
sep = maximum (0:zipWith (+) lr rl) `div` 2 + 1
ll' = 0 : overlay (map (+sep) ll) (map (subtract sep) rl)
rr' = 0 : overlay (map (+sep) rr) (map (subtract sep) lr)
-- overlay xs ys = xs padded out to at least the length of ys
-- using any extra elements of ys
overlay :: [a] -> [a] -> [a]
overlay [] ys = ys
overlay xs [] = xs
overlay (x:xs) (y:ys) = x : overlay xs ys
爲什麼'x1'和'sep'的計算不會導致infinit循環? 他們是如何計算的?
非常感謝。我可以完全理解一個小例子中的非嚴格評估,但在嘗試閱讀長代碼時仍會迷失方向,更不用說使用它。那麼,這種編碼風格推薦?如果是,我可以在哪裏瞭解更多信息? – realli
當非嚴格的「深度」達到一定深度時,我也會發現這種非嚴格評估的漏洞,特別是一個「棘手的代碼」。但我認爲,對於某些類型的算法,這可能會導致更好的性能特徵。 – Ankur
事實上,有時候清晰的代碼會更好,有時候「棘手的代碼」會勝出。我應該學會更多地瞭解這種技巧。 – realli