首先,你mirrorXY'
可以用高階函數map
和iterate
,而不是直接遞歸編寫:
mirr m = map (map head) . iterate (map tail) $ m
...這打擊了在碰到空列表,因爲你已經發現:
*Main> map (map head) . iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[*** Exception: Prelude.head: empty list
讓我們嘗試一下沒有第一部分:
*Main> iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[[1,2,3,4],[2,3,4,5],[3,4,5,6]],[[2,3,4],[3,4,5],[4,5,6]],[[3,4],[4,5],[5,6]],[
[4],[5],[6]],[[],[],[]],[*** Exception: Prelude.tail: empty list
*Main>
所以很容易修復:我們只需要停止在碰到[]
輸入列表:
*Main> takeWhile (not.null.head) . iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[[1,2,3,4],[2,3,4,5],[3,4,5,6]],[[2,3,4],[3,4,5],[4,5,6]],[[3,4],[4,5],[5,6]],[
[4],[5],[6]]]
因此,功能
mirr xs = map (map head) . takeWhile (not.null.head) . iterate (map tail) $ xs
這預示着所有的子表都同樣長度(或至少所述第一個是最短的),但是,很容易通過調整測試中takeWhile
修復:
mirr xs = map (map head) . takeWhile (all (not.null)) . iterate (map tail) $ xs
另請參閱[轉置](http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#transpose) – Rotsor 2012-07-06 17:29:51
@Rotsor,我已經提到過在你發表評論之前,在問題中使用'transpose'。 – fadedbee 2012-07-08 16:11:38