Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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
List Haskell函数交换列表中的每一个元素_List_Haskell_Recursion - Fatal编程技术网

List Haskell函数交换列表中的每一个元素

List Haskell函数交换列表中的每一个元素,list,haskell,recursion,List,Haskell,Recursion,我想知道如何在Haskell中交换列表中的每一个元素 示例输出应如下所示: swap [1,2,3,4,5] [2,1,4,3,5] 到目前为止,我得到的是 swap :: [a] -> [a] swap [] = [] swap (x:xs) = head xs : [x] 但是,这只交换前两个元素,当我尝试加载包含函数的文件时,任何使函数递归的尝试都会导致错误。如何使其递归?您需要一次提取两个元素: swap [] = [] swap (x:y:rest) = y:x:

我想知道如何在Haskell中交换列表中的每一个元素

示例输出应如下所示:

swap [1,2,3,4,5]  
[2,1,4,3,5]
到目前为止,我得到的是

swap :: [a] -> [a]  
swap [] = []  
swap (x:xs) = head xs : [x]

但是,这只交换前两个元素,当我尝试加载包含函数的文件时,任何使函数递归的尝试都会导致错误。如何使其递归?

您需要一次提取两个元素:

swap [] = []
swap (x:y:rest) = y:x:(swap rest)
swap [x] = [x]

最后一行需要允许奇数长度列表——它匹配长度正好为1的列表,因此它不会与其他两种情况(长度为0,长度为2或更多)重叠。

@j_random_hacker的解决方案更好,但是,如果您希望看到实现完成,可以尝试以下方法:

swap [] = []
swap (x:[]) = [x]
swap (x:xs) = head xs : x : (swap $ tail xs)
但是请注意,
head
tail
的使用是不必要的,模式匹配可以使这里的内容更加清晰

import Data.Function(on)

swap = map snd . concatMap reverse . groupBy ((==) `on` fst) . zip (cycle "aabb")

不要把我的解决方案看得太重,我只是想改进我的Haskell-Foo…

除了其他非常优秀的回答之外,这里有一个使用一些非常方便的库的解决方案。首先是install,它提供了许多很好的拆分列表的方法。我们解决这个问题的策略是首先将列表拆分为大小为2的块,然后交换每个块,然后将结果连接回一个平面列表。以下是关键功能的工作原理:

Prelude Data.List.Split> chunk 2 [1..11]
[[1,2],[3,4],[5,6],[7,8],[9,10],[11]]
要交换每个块的元素,我们只需调用
reverse
。因此,最终结果是:

Prelude Data.List.Split> let swap = concat . map reverse . chunk 2
Prelude Data.List.Split> swap [1..5]
[2,1,4,3,5]

显示您的尝试及其导致的错误如何?我试图做的是交换(x:xs)=头xs:[x]交换xs。尝试加载文件时出现的错误是“haskell.hs:3:25:函数
[x]”应用于两个参数,但其类型
[a]'在
(:)”的第二个参数中没有,即表达式中的
[x]swap-xs]swap-xs:“swap”(x:xs)=head xs x]交换xs失败,模块已加载:无。“在
(x:y:rest)
案例之后,空模式和单元素模式可以更简洁地表示为
swap other=other
。感谢您的帮助。我已经通过添加swap[x]=[x]@Chuck:True,找到了如何使您的代码在奇数大小的列表中工作的方法,但是您必须将这种情况放在最后,因为它与另一种情况重叠。当案例不相交时,我感觉更舒服,因为它们可以按任何顺序排列(也许这是糟糕的风格?@j_random_hacker:不幸的是,我的风格鉴定人是清洁工,但就个人而言,我更看重简洁而不是“随机重新排列行并使其工作的能力”在Haskell代码中,在正常情况下使用catchall是非常正常的,所以我认为这不会让任何人失望。