列表的递归函数

时间:2014-04-14 15:05:12

标签: haskell

我对haskell上的递归函数有点困惑,有人可以更好地解释一下吗?

cut [] = ([],[])
cut (x:[]) = ([x],[]) 
cut (x:y:l) = let (xs,ys) = cut l
             in (x:xs,y:ys)

P.S。 :"让...在"部分让我很困惑!

3 个答案:

答案 0 :(得分:1)

Haskell let具有以下语法:let <bindings> in <expression>

所以你创建了一些绑定并在表达式中使用它。

示例:

λ> let a = 3 in a + 3
6

cut函数的类型为cut :: [a] -> ([a], [a])

因此,函数cut返回类型为([a],[a])的元组,这正是切割函数的let表达式中模式匹配的元素。变量xs与元组的第一个元素模式匹配,即[a],下一个变量ys与元组的第二个元素模式匹配,这是另一个列表。

答案 1 :(得分:1)

cut [] = ([],[])
cut (x:[]) = ([x],[]) 

这些是边缘条件,

cut (x:y:l) = let (xs,ys) = cut l
              in  (x:xs,y:ys)

是递归部分。在其中,

  1. 模式匹配(x:y:l)会将cut的参数列表分为三部分,第一个元素将绑定到x,第二个元素绑定到y },其余的到l

  2. let (xs, ys) = cut l表示将cut应用于l,结果应该是一对,并将其第一部分绑定到xs,第二部分绑定到ys cut (x:y:l)

  3. 在这种情况下,(x:xs,y:ys)的值为{{1}}。

答案 2 :(得分:1)

我将逐步完成一个例子,希望它会让事情变得更加清晰。首先让我建立以下行号:

1.  cut [] = ([],[])
2.  cut (x:[]) = ([x],[]) 
3.  cut (x:y:l) = let (xs,ys) = cut l
                  in (x:xs,y:ys)

使用以下调用作为示例:

cut [0,1,2]

这匹配第3行的子句,因为列表至少有2个元素。因此x = 0y = 1l = [2]。所以它评估如下:

let (xs,ys) = cut [2]
              in (0:xs, 1:ys)

cut [2]匹配第2行的子句,x绑定到2。

let (xs,ys) = ([2], [])
             in (0:xs, 1:ys)

然后我们得出结论xs = [2]ys = []

(0:[2], 1:[])

与以下内容相同:

([0,2], [1])

所以这个函数正在做的是将一个列表拆分为两个,方法是将偶数索引放在第一个列表中,将奇数索引放在第二个列表中。