Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 按负责人分列的单独清单_Haskell - Fatal编程技术网

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
    将导致抛出异常(尝试在GHCi
    head[]
    中运行)
  • 为简单起见,我假设所有列表都已被检查为具有相同的长度(
    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]]