这个操作有标准名称吗?

时间:2015-09-29 18:32:20

标签: haskell functional-programming list-processing

因此,在处理Haskell项目时,我最终编写了以下函数

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

对于那些不讲Haskell的人,这需要一个矩阵列表,并将相应的行连接到一个新的矩阵中。

它在这个项目中出现了几次,我觉得这是我错过的一种常见操作。

此操作是否有标准名称?正在搜索Hoogle

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

没有任何用处。

2 个答案:

答案 0 :(得分:4)

你的功能与这个功能非常相似(但不完全相同):

reGrid' = map concat . transpose

例如,我的QuickCheck属性\xs -> reGrid xs == reGrid' xs显示了这种差异:

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

简而言之,您的版本将“切断”您可能真正关心(或不关注)的更多内容。有一个更有说服力的例子:

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

您可以自己判断他们不同的情况是否与您有关。

答案 1 :(得分:2)

你有很多东西,你想把它们变成一件事。通常的方法是使用某种折叠。让我们开始吧:

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

现在假设你有一个矩阵,你也可以重新网格化其余的矩阵。你怎么能把它们结合起来?好吧,你想把这些行合并在一起,直到一个用完,这听起来像zipWith的工作。所以把所有东西放在一起,

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

这不是一个标准功能,但它很简短,不会出现部分功能。但是,如果列表很长,它确实存在效率问题。要解决这个问题,你可以切换到左侧折叠,但是获得严格的权限将是棘手的。我可以稍后写出来。