我对haskell上的递归函数有点困惑,有人可以更好地解释一下吗?
cut [] = ([],[])
cut (x:[]) = ([x],[])
cut (x:y:l) = let (xs,ys) = cut l
in (x:xs,y:ys)
P.S。 :"让...在"部分让我很困惑!
答案 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)
是递归部分。在其中,
模式匹配(x:y:l)
会将cut
的参数列表分为三部分,第一个元素将绑定到x
,第二个元素绑定到y
},其余的到l
let (xs, ys) = cut l
表示将cut
应用于l
,结果应该是一对,并将其第一部分绑定到xs
,第二部分绑定到ys
cut (x:y:l)
在这种情况下,(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 = 0
,y = 1
和l = [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])
所以这个函数正在做的是将一个列表拆分为两个,方法是将偶数索引放在第一个列表中,将奇数索引放在第二个列表中。