concat是否返回可折叠状态?

时间:2018-07-23 16:52:40

标签: haskell

Prelude> :t concat
concat :: Foldable t => t [a] -> [a]

通过查看上面的类型信息,我知道返回的值不是 Foldable 类型类的派生。因此,在下面的代码中,我期望行 dd = concat [cc,aa] 失败,因为cc不是 Foldable 。但是,您可以注意到,它为什么起作用?

Prelude> aa = [1,2]
Prelude> bb=[3,4]
Prelude> cc = concat[aa,bb]
Prelude> dd=concat [cc,aa]
Prelude> dd
[1,2,3,4,1,2]

谢谢!

2 个答案:

答案 0 :(得分:6)

concat :: Foldable t => t [a] -> [a]

concat的阅读方式是折叠列表的集合并返回列表。只要生成的东西是可折叠的,t就可以代替很多东西。

concat :: [[a]] -> [a]
concat :: ZipList [a] -> [a]
concat :: Set [a] -> [a]

这些都是此功能的所有有效专长。因此,我们可以向其传递一个列表列表,一个列表压缩列表,一组列表或Haskell生态系统中可用的众多其他容器。

现在,就您而言,您将创建列表aabb。所以 1

aa :: [Int]
bb :: [Int]

现在,正如我们所说,列表是可折叠的,因此[]是上述类型中t的有效替代品。那你就

let cc = concat [aa, bb]

您要将列表列表传递给concat,因此您使用的特定版本是

concat :: [[Int]] -> [Int]

所以cc的类型是

cc :: [Int]

同样,用[cc, aa]调用不会造成任何问题,因为您静止会传递列表列表,因此我们使用与以前相同的专业化方法。

dd :: [Int]

我希望这会有所帮助!如果习惯了OOP的“ is-a”风格关系,那么习惯Haskell的基础结构可能会造成混乱。


1 为简单起见,我假设类型为Int。严格来说,您的变量具有完全Num a => [a]的类型,可以再次专门用于[Int]。但是我想您还是会认为它们是整数,所以这不是重点。

答案 1 :(得分:3)

每个列表都是可折叠的;除列表外,还有其他可折叠类型。其他示例包括VectorSeqconcat始终返回列表。

concat的输入为Foldable t => t [a]。满足Foldable约束的一种类型是[[Int]]-(整数列表)的列表。另一个将是Vector [Int]。内部总是列表,但是外部可以变化。

在两次调用concat的过程中,您传递一个[[Int]]-命名的内部列表aabbcc和外部集合[]concat的行中。

ccaabb具有相同的类型。我一直将其写为[Int]。 GHCi将给出更通用的类型Num a => [a],表示您喜欢的任何数字类型的列表a-IntFloatDouble,{{1 }}。