我在没有任何函数式编程背景的情况下学习f# -开始取得进展,但在这一点上停滞不前。有人能帮助我理解99个f#问题中的问题9的解决方案吗?他们可以在这里找到:http://fssnip.net/an
基本上,我不理解模式匹配在所提供的解决方案中是如何工作的。首先,什么是xss?为任何帮助干杯!
问题9:将列表元素的连续副本打包到子列表中。如果列表包含重复的元素,则应将它们放在单独的子列表中。
示例:
压缩'a';'b';'c';'c';'a';'a';'d';'e';'e‘
val it : char list list = ['a';'b';'c';'c';'a';'a';'d';'e';'e']
样本解决方案;
let pack xs =
let collect x = function
| (y::xs)::xss when x = y -> (x::y::xs)::xss
| xss -> [x]::xss
List.foldBack collect xs []发布于 2013-02-14 06:58:51
要理解这一点,首先要了解列表在F#中是如何表示的。F#列表可以是:
[]或head::tail的列表(尾
因此,例如,如果您编写[ 1; 2; 3 ],您实际上是在构造一个包含1的列表,后跟一个包含2的列表,(依此类推)后面跟着一个空列表。该表达式被编译为:
1::(2::(3::[])) 您可以省略括号,只编写1::2::3::[]。
模式匹配使用完全相同的语法,但方向相反。你不是在构造列表,而是分解它们。因此,当您有一个模式x::xs时,这意味着您希望获取第一个元素并将其赋给一个变量x,而剩余的列表应该赋值给一个变量xs。
模式(x::xs)::xss稍微有点棘手,因为它适用于列表列表。这意味着您匹配的列表的头部也是一个列表。您可以将代码重写为以下更简单的版本:
let pack xs =
let collect x = function
| head::xss -> // Decompose into first element (head) and the rest (tail)
match head with
| y::xs when x = y -> (x::y::xs)::xss
| _ -> [x]::xss
| xss -> [x]::xss
List.foldBack collect xs []现在您在代码中有了一些重复,但是您可以看到collect接受x和另一个参数,将另一个参数与head::xss进行匹配(以获得头部/尾部),然后也分解head。
发布于 2013-02-14 06:49:01
(y::xs)::xss匹配列表的(非空)列表,y和xs是第一个子列表的头部和尾部,xss是外部列表的尾部。在第二种情况下,xss匹配整个列表(无论是否为空)。
foldBack (('T -> 'State -> 'State) -> 'T list -> 'State -> 'State)将累加器参数从后到前遍历列表。
collect是“累加”函数,它基本上是这样的:如果状态(最初是一个空列表)包含至少一个子列表,该子列表也是非空的,并且当前元素(x)与子列表(y)的头部匹配,则将x附加到子列表,否则将新的子列表附加到仅由x组成的状态(xss)。每个子列表是一组相等的相邻元素。
https://stackoverflow.com/questions/14864631
复制相似问题