Haskell 按负责人分列的单独清单
我在尝试将下面的列表分开时遇到问题,假设我们有下面的列表Haskell 按负责人分列的单独清单,haskell,Haskell,我在尝试将下面的列表分开时遇到问题,假设我们有下面的列表 结果应该是: [[1,5,9,13] [2,6,10,14] [3,7,11,16] [4,8,12,16]] 我试着用以下方法来做: joinHead (x: xs) = map head (x: xs) separateLists (x: xs) = xs joinHead x ++ separateLists 显然,这是行不通的。我希望你能帮助我。thx.我修改了您编写的函数,joinHead和separateLists,以
结果应该是:
[[1,5,9,13] [2,6,10,14] [3,7,11,16] [4,8,12,16]]
我试着用以下方法来做:
joinHead (x: xs) = map head (x: xs)
separateLists (x: xs) = xs joinHead x ++ separateLists
显然,这是行不通的。我希望你能帮助我。thx.我修改了您编写的函数,
joinHead
和separateLists
,以使代码正常工作,同时保留您遵循的逻辑。从这些函数中我可以推断出,使用joinHead
提取每个子列表的第一个元素并返回一个新列表。然后,这个新列表应该被插入递归调用separateLists
返回的列表的前面
以下是joinHead
的新定义:
joinHead :: [[a]] -> [a]
joinHead ([]:_) = []
joinHead xs = map head xs
请注意,第一行通过模式匹配检查列表列表中包含的第一个列表是否为空,如果为空,则返回一个空列表([]
)。原因有二:
head
不安全。这意味着对空列表调用head
将导致抛出异常(尝试在GHCihead[]
中运行)李>
length(xs!!0)==length(xs!!1)…
)separateLists
的定义如下:
separateLists :: [[a]] -> [[a]]
separateLists ([]:_) = []
separateLists ([x]:xs) = [joinHead ([x]:xs)]
separateLists xs = joinHead xs : separateLists (map tail xs)
同样,前两个定义对于停止递归和安全目的都是必要的。第一行显示:“如果第一个列表为空,则所有列表的所有元素都已被使用,因此返回[]
”。第二行说:“如果第一行正好有一个元素,那么只需调用joinHead
,并返回包装在列表中的结果”。请注意,在第三个定义中,我们调用了tail
,它与head
一样,在调用[]
时抛出异常。这就是为什么长度为1的列表需要一个单独的案例的原因。最后,对于长度大于1的列表执行的第三行从joinHead xs
获取一个列表,并将其插入(使用“cons”操作符(:)
)从递归调用separateLists
返回的列表的开头。在这个调用中,我们必须取出所有列表的第一个元素,这就是为什么我们使用map tail xs
现在,运行:
λ: let list = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16,17]]
λ: separateLists list
[[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]
会给你预期的结果。我希望这足够清楚。最后,我想指出的是,这种实现远远不是最佳的,正如评论中所建议的,您可能应该使用标准的
Data.List.transpose
。作为练习和教学示例,这很好!;-) 你看过吗?您可以从文档中查看源代码,并查看它是如何在那里实现的。尝试将其从列表理解转换为使用map
。事实上,甚至写下签名以找到此的标准实现…非常感谢,现在我了解了如何正确工作,当您是这门语言的新手时,这有点复杂。再次感谢您的帮助:)
λ: let list = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16,17]]
λ: separateLists list
[[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]