2015-09-29 67 views
2

所以在Haskell的項目工作,我已經結束了寫下面的函數此操作是否有標準名稱?

reGrid :: [[[a]]] -> [[a]] 
reGrid [] = [] 
reGrid xs | any null xs = [] 
      | otherwise = (concat $ map head xs) : reGrid (map tail xs) 

對於那些誰也不說話哈斯克爾,這需要矩陣的名單,並加入相應的行成新矩陣。

它在這個項目中彈出了好幾次,我覺得這是我錯過的某種常見操作。

此操作是否有標準名稱?在Hoogle搜索

[[[a]]] -> [[a] 

產量沒有用。

回答

2

你有一堆東西,你想把它們變成一件事。通常的做法是有某種摺疊。因此,讓我們開始與:

regrid [] = [] 
regrid xs = foldr go (repeat []) xs 

現在,假設你有一個矩陣,你也有重新網格化,其餘的結果。你怎麼能把它們結合起來?那麼,你想合併行直到一個用完,這聽起來像一個工作zipWith。因此,把所有東西放在一起,

regrid = foldr (zipWith (++)) [] 

這不是一個標準功能,但它很短,並沒有猴子部分功能。但是,如果名單很長,它確實存在效率問題。爲了解決這個問題,你可以切換到左邊的摺疊區域,但是嚴格的正確性會很棘手。我可以稍後再寫。

+0

正是我在找的東西。有一點需要注意的是,你的初始值需要是一個列表的列表,它與輸入列表的長度相等,否則它不會實際到達任何行,即'let reGrid2 xs = foldr(zipWith(++ ))(複製(長度xs)[])xs'。 – user2085282

+0

@ user2085282,修正,但不同。 – dfeuer

4

你的功能非常類似(但不相同)這一個:

reGrid' = map concat . transpose 

例如,我的快速檢查物業\xs -> reGrid xs == reGrid' xs變成了這種差異:

*Main> reGrid [[[]],[]] 
[] 
*Main> reGrid' [[[]],[]] 
[[]] 

總之,你的版本會「切斷」更多你可能真正關心(或不關心)的東西。舉個更具說明性的例子:

*Main> reGrid [["abc"],[]] 
[] 
*Main> reGrid' [["abc"],[]] 
["abc"] 

你可以自己判斷他們與你有什麼不同的情況。