F#(Fsharp)解压函数解释



我正在上一门使用F#的函数编程大学课程,我一直对下面程序的逻辑流程感到困惑。有人愿意解释一下吗?

let rec unzip = function
|    []          ->  ([],[])
|    (x,y)::rest ->
let (xs,ys) = unzip rest
(x::xs,y:ys);;

因此,这个程序应该获取一对列表,并输出一对列表。

[(1,'a');(2,'b')] -> ([1;2],['a','b'])

在我看来,就像基本情况一样,参数(列表(是空的,输出的格式是给定的,但我不明白第三行和第四行是如何计算的。

let (xs,ys) = unzip rest
(x::xs,y:ys);;

首先,这是一个递归函数-rec关键字是给定的:(。

这些可能很难让你了解,但在函数式编程中很常见。

我假设您对正在进行的大多数模式匹配都很满意,并且知道function关键字的简写。

let rec unzip = function
|    []          ->  ([],[])
|    (x,y)::rest ->
let (xs,ys) = unzip rest
(x::xs,y:ys);;

你似乎很满意:

|    []          ->  ([],[])

给定一个空列表,返回一个包含2个空列表的元组。这不仅仅是一个保护子句,它稍后将用于停止递归程序永远运行。

下一点。。。

|    (x,y)::rest ->

获取列表的第一个元素(头(,并将其从尾部拆分。它还将作为元组的头元素分解为两个值xy

可以手写为:

|    head::rest ->
let x,y = head

现在是它自称的有趣部分:

let (xs,ys) = unzip rest
(x::xs,y:ys);;

通过一个例子来了解每一步发生的事情可能会有所帮助:

unzip [(1,'a');(2,'b');(3,'c')]
x = 1
y = 'a'
rest = [(2,'b'); (3,'c')]
unzip rest
x = 2
y = 'b'
rest = [(3,'c')]
unzip rest
x = 3
y = 'c'
rest = []
unzip rest
return [],[]
xs = []
ys = []
return [x:xs],[y:ys]     # 3:[] = [3], 'c':[] = ['c']
xs = [3]
ys = ['b']
return [x:xs],[y:ys]      # 2:[3] = [2,3], 'b':['c'] = ['b', 'c']
xs = [2,3]
ys = ['b','c']
return [x:xs],[y:ys]       # 1:[2;3] = [1,2,3], ['a']:['b';'c'] = ['a', 'b', 'c']
done

最新更新