concat返回可折叠?

vin*_*ngo 1 haskell

Prelude> :t concat
concat :: Foldable t => t [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

查看上面的类型信息,我理解返回的值不是可折叠类型类的派生.因此,在下面的代码中,我期望dd = concat [cc,aa]行失败,因为cc不是可折叠的.但是,你可以注意到,它有效,为什么?

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]
Run Code Online (Sandbox Code Playgroud)

谢谢!

Sil*_*olo 6

concat :: Foldable t => t [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

我们阅读本文的方式concat采用可折叠的列表集合并返回列表.t可以替代很多东西,只要结果是可折叠的.

concat :: [[a]] -> [a]
concat :: ZipList [a] -> [a]
concat :: Set [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

这些都是此功能的有效特化.因此,我们可以传递一个列表列表,列表的列表,一组列表,或Haskell生态系统中可用的无数容器中的任何其他容器.

现在,在您的情况下,您制作列表aabb.所以1

aa :: [Int]
bb :: [Int]
Run Code Online (Sandbox Code Playgroud)

现在,正如我们所说,列表是可折叠的,因此在上面的类型中[]是有效的替换t.然后你做

let cc = concat [aa, bb]
Run Code Online (Sandbox Code Playgroud)

您正在传递列表列表concat,因此您使用的特定版本是

concat :: [[Int]] -> [Int]
Run Code Online (Sandbox Code Playgroud)

cc类型也是如此

cc :: [Int]
Run Code Online (Sandbox Code Playgroud)

同样,调用它[cc, aa]不会导致任何问题,因为您仍然传递列表列表,因此我们使用与以前相同的专业化.

dd :: [Int]
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!如果你已经习惯了OOP的"is-a"风格关系,那么习惯Haskell的基础设施可能会令人困惑.


1Int为了简单而假设类型.严格地说,你的变量完全具有通用性,它们的类型Num a => [a]也可以专门用于[Int].但我想你无论如何都认为它们是整数,所以这就不合时宜了.