如何展平haskell中的列表列表

Posted

技术标签:

【中文标题】如何展平haskell中的列表列表【英文标题】:How to flatten a list of lists of lists in haskell 【发布时间】:2014-04-22 22:47:18 【问题描述】:

我想做的就是我所要求的。函数的类型签名应该是这样的:

flatten::[[[Int]]] -> [[Int]]

我试图搜索一些扁平化代码,但它们定义了新类型,这让我感到困惑。有什么帮助吗?提前致谢。

【问题讨论】:

Hoogle 有帮助。 ;) 展平有两种方法。你是指哪一个? [[[1,2],[3,4]],[[5,6],[7,8]]] -> [[1,2,3,4],[5,6,7,8]][[[1,2],[3,4]],[[5,6],[7,8]]] -> [[1,2],[3,4],[5,6],[7,8]] ^^^ 那是 fmap joinjoin 【参考方案1】:

有(至少)两种写法

flatten::[[[Int]]] -> [[Int]]

一个是

flatten1 = concat
-- Example: flatten [[[1], [2]], [[3]]] = [[1], [2], [3]] :: [[Int]]

另一个是

flatten2 = map concat
-- Example: flatten [[[1], [2]], [[3]]] = [[1,2], [3]] :: [[Int]]

基本上,flatten1 将括号的“中间”级别展平,而flatten2 将括号的“最内”级别展平。

作为一个练习,你可能想说服自己

concat . flatten1 = concat . flatten2 :: [[[Int]]] -> [Int]

确实,在上面的示例中,两者都会产生[1,2,3]

更高级的评论

上面的定律实际上是一个非常有名的定律,因为它是一元定律的一个特例

join . fmap join = join . join :: Monad m => m (m (m a)) -> m a

m = [](即在列表 monad 中)和a=Int

【讨论】:

【参考方案2】:

你正在寻找

concat :: [[a]] -> [a]

在您的用例中,元素类型恰好是 [Int]

【讨论】:

【参考方案3】:

找到像您这样的问题的答案的最佳方法之一是使用 hoogle。例如见 http://www.haskell.org/hoogle/?hoogle=%5B%5B%5Ba%5D%5D%5D+-%3E+%5B%5Ba%5D%5D。

concat 函数在结果列表中排名第二。

还有 hayoo:http://holumbus.fh-wedel.de/hayoo/hayoo.html 搜索所有hackage。

【讨论】:

以上是关于如何展平haskell中的列表列表的主要内容,如果未能解决你的问题,请参考以下文章

Haskell,树中的列表列表

Haskell 中的列表是归纳的还是归纳的?

Haskell如何知道`xs`是函数定义中的列表?

seq如何评估Haskell中的无限列表?

我如何过滤Haskell列表中的许多条件?

为啥haskell中的递归列表这么慢?