zip功能中的Haskell冒号

Jon*_*anz 1 haskell

我很难理解这个Haskell函数.我知道它表面上做了什么,但我不确定它是如何实现这一功能的.

zip (x:xs) (y:ys) = (x,y) : zip xs ys 
zip xs ys = [ ]
Run Code Online (Sandbox Code Playgroud)

我的想法:

  1. zip 是函数的名称.
  2. zip需要2个参数.(我相信currying在这里并不重要).
  3. 参数是(x:xs)(y:ys)
  4. zip返回元组类型的列表(x,y).

现在我不太了解参数

(x:xs) (y:ys)
Run Code Online (Sandbox Code Playgroud)

冒号将一些内容添加到列表的开头(返回列表),那么我们为什么要将某些内容添加到我们想要压缩的列表中呢?什么是xy功能定义?

右侧看起来很明显:我们将元组(x,y)插入(0)到zip返回的元组列表中.

(x,y) : zip xs ys 
Run Code Online (Sandbox Code Playgroud)

现在,zip xs ys = [ ]如果我们只传递2个列表,为什么我们总是想要一个空列表呢?

你能解释下面的调用是如何zip进行评估的:

zip [5,7,9] [1,3,5,11]
Run Code Online (Sandbox Code Playgroud)

Wil*_*ess 6

(x:xs)等式的左手侧是图案.它解构了一个论点.

(x:xs)等式的右手边是一个表达式.它构造了一个值.

zip (x:xs) (y:ys) = 
Run Code Online (Sandbox Code Playgroud)

意味着,zip是一个函数,期望两个参数,两者都应该是非空列表.

                      (x,y) : zip xs ys 
Run Code Online (Sandbox Code Playgroud)

这构造了一个输出值; 它的头是(x,y),它的尾巴是调用的结果zip xs ys:

       [ x1,   x2, x3, x4, ....
       [ y1,   y2, y3, y4, ....
      --------------------------
    [ (x1,y1) , ................
Run Code Online (Sandbox Code Playgroud)

尝试调用zip (5,7,9) (1,3,5,11)将不起作用(将导致编译时类型不匹配错误),因为这里的第一个rgument是三元组,而第二个 - 4元组; 这些不是清单.列表具有不同的大小,但元组具有固定的大小.因此,正确的呼叫zip [5,7,9] [1,3,5,11].你可以看到由数字代入上述方案的它是如何(即什么结果描述)减少到一个值,x1,y1,x2,等.

当其中一个列表用完时,呼叫将是zip [] [11].上述等式与此情况不符.幸运的是,你有另一个等式,

zip xs ys = 
Run Code Online (Sandbox Code Playgroud)

它使用变量作为模式.这是一个无可辩驳的模式的例子; 它总是成功的.因此,无论这两个论点是什么,第一个将在今后被称为xs第二个 - ys和等式的右边

               [ ]
Run Code Online (Sandbox Code Playgroud)

将输入,表示[]将始终生成该值.它的作用是当列表参数zip具有不同的长度时,将忽略较长列表的额外元素.


luq*_*qui 5

让我们使用一个更简单的例子:

head (x:xs) = x
Run Code Online (Sandbox Code Playgroud)

要意识到的事情是列表[1,2,3]是简写1:2:3:[],1:(2:(3:[]))因为它(:)是右关联的再次简写.所以服用

head [1,2,3]
Run Code Online (Sandbox Code Playgroud)

那是一样的

head (1:(2:(3:[])))
Run Code Online (Sandbox Code Playgroud)

现在我们可以看到模式如何类似于输入.

head (1:(2:(3:[])))
      ^  ^^^^^^^^
head (x:   xs     )
Run Code Online (Sandbox Code Playgroud)

所以x1xs2:(3:[]),换句话说[2,3].


解释一下模式匹配.第一个等式zip

zip (x:xs) (y:ys) = ...
Run Code Online (Sandbox Code Playgroud)

两个列表至少有一个元素时匹配(因为空列表不是表单a:b).第二个等式

zip xs ys = ...
Run Code Online (Sandbox Code Playgroud)

如果第一个等式不匹配(并且它们是正确的类型,因为Haskell是静态类型的),则匹配任何参数.

  • `[]:[]`是`[[]]` - 一个元素的列表(这是一个空列表).它的head元素是`[]`,它的尾是`[]` - 也就是说,那里没有元素. (2认同)