List 如何编写函数';成对';在哈斯克尔?

List 如何编写函数';成对';在哈斯克尔?,list,haskell,tuples,List,Haskell,Tuples,pairs函数需要执行以下操作: pairs [1, 2, 3, 4] -> [(1, 2), (2, 3), (3, 4)] 为了完整起见,使用显式递归的更“低级”版本: pairs (x:xs@(y:_)) = (x, y) : pairs xs pairs _ = [] 结构x:xs@(y:)表示“一个列表,其头部x,尾部xs,至少有一个元素y”。这是因为y同时作为当前对的第二个元素和下一对的第一个元素。否则,我们必须对长度为1的列表进行特殊处理 pairs [

pairs函数需要执行以下操作:

pairs [1, 2, 3, 4] -> [(1, 2), (2, 3), (3, 4)]

为了完整起见,使用显式递归的更“低级”版本:

pairs (x:xs@(y:_)) = (x, y) : pairs xs
pairs _          = []
结构
x:xs@(y:)
表示“一个列表,其头部
x
,尾部
xs
,至少有一个元素
y
”。这是因为
y
同时作为当前对的第二个元素和下一对的第一个元素。否则,我们必须对长度为1的列表进行特殊处理

pairs [_] = []
pairs []  = []
pairs (x:xs) = (x, head xs) : pairs xs
你可以走得更远

import Control.Applicative (<*>)
pairs = zip <*> tail

可能更清楚。

呼叫阿兹特克连续数字之神:

import Control.Monad (ap)
import Control.Monad.Instances() -- for Monad ((->) a)

foo = zip`ap`tail $ [1,2,3,4]

您只需要第二行就可以了,因为
zip[]undefined
[]
@rampion:您确实需要知道zip在内部是如何工作的,这样才能知道情况,这意味着zip(tail xs)xs将无法工作。这似乎不是编写清晰明了的代码的好方法。另一方面,有没有在某个地方包含此函数的库?@RobertMassaioli:不正确。您不需要知道
zip
在内部是如何工作的,只需知道
zip
在其第一个参数中是严格的,但在其第二个参数中是有条件严格的,这在Haskell中是其接口语义的一部分。在其他语言中,是的,这可能是一个实现细节,但不是Haskell。@RobertMassaioli:我在任何库中都没有看到这个函数<代码>对(x:y:rest)=(x,y):对(y:rest)也可以工作,避免了对
@
的需要,尽管需要额外的构造函数。太棒了!我是个新手,所以我花了大约30分钟的时间才明白为什么
zip-tail
有效,但这完全值得。如果其他人也好奇,看看这里:在这个过程中,阅读LYAH的第11章。引用得很好:“Applicative的另一个实例是(->)r,所以函数。它们很少与code golf[…]之外的应用程序风格一起使用。”根据pointfree.io,
pairs=ap zip tail
也可以工作,因为
ap
类似于
,但对于monad。
pairs xs = zip xs (tail xs)
import Control.Monad (ap)
import Control.Monad.Instances() -- for Monad ((->) a)

foo = zip`ap`tail $ [1,2,3,4]