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)
谢谢!
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生态系统中可用的无数容器中的任何其他容器.
现在,在您的情况下,您制作列表aa和bb.所以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的基础设施可能会令人困惑.
1我Int为了简单而假设类型.严格地说,你的变量完全具有通用性,它们的类型Num a => [a]也可以专门用于[Int].但我想你无论如何都认为它们是整数,所以这就不合时宜了.