2011-05-25 62 views
2

我理解并写了F#的典型功率设置功能(类似于算法Wikipedia混淆F#List.Fold(幂函数)

后来我发现这个实现幂的,这似乎不错,紧凑,期待我不理解它。

let rec powerset = function 
        | [] -> [[]] 
        | h::t -> List.fold (fun xs t -> (h::t)::t::xs) [] (powerset t); 

我打破了这种下降到1个步骤非递归函数来查找的幂[1; 2]和在端部硬编码的功率设定的2的值[[2]; []]

let right = function 
        | [] -> [[]] 
        | h::t -> List.fold (fun acc t -> (h::t)::t::acc) [] [[2]; []]; 

输出是[[1]; []; [1; 2]; [2]]这是正确的。

但是我期待List.Fold输出[[1; 2]; []; [1; 2]; [2]]

因为我不确定't',所以我修改了变量名,并且确实得到了我的预期。当然,这不是[1; 2]的正确权力。

let wrong = function 
        | [] -> [[]] 
        | h::t -> List.fold (fun acc data -> (h::t)::data::acc) [] [[2]; []]; 

对我来说,“T”(一个withing乐趣,而不是为H :: T)简直就是第二个参数为“好玩”的名称,但是这显然不是这样的。那么我写的“正确”和“错误”F#函数有什么区别?这里的“t”究竟是指什么?

谢谢! (我是F#的新手)

回答

2

在您的“正确”示例中,t最初是模式匹配中值绑定的名称,但它在传递给List.fold的lambda表达式中由参数t隐藏。而在你的“错误”例子中,t被捕获为lambda表达式中的闭包。我想,也许你不打算这样捕获,而不是你想要的:

//now it works as you expect, replaced "t" with "data" in your lambda expression. 
let wrong = function 
        | [] -> [[]] 
        | h::t -> List.fold (fun acc data -> (h::data)::data::acc) [] [[2]; []]; 
+0

谢谢!这正是我需要的,现在整个功能都是有意义的。 't'arg让我寻找不存在的模式:)! – Preets 2011-05-25 15:52:20

+0

@Preets:不客气! – 2011-05-25 16:23:40

-4

t是一个通过模式匹配绑定的变量。 List.fold是避免显式循环的奇特方式。现在,阅读一些关于F#的介绍性教程。

+0

我没有读到List.Fold和t(尾),但我不明白“T”一折内表示。这是明显的吗?我很抱歉,但我只是看不到它: -/ – Preets 2011-05-25 15:35:10

+0

“t”是否已经指向(h :: t)的尾部? – Preets 2011-05-25 15:38:45

1
let rec powerset = function 
        | [] -> [[]] 
        | h::t -> List.fold (fun xs t -> (h::t)::t::xs) [] (powerset t); 

这里是代码的理解/英文翻译:

  1. ,如果列表(要功率)为空,则返回一个列表,其中包含在它

  2. 空列表,如果该列表是h::t(头h,其余为t,所以h是一个元素,t是一个列表)。然后:

    A. (powerset t):计算电源组的t

    B. (fun xs t -> (h::t)::t::xs)意味着应用/折叠此功能可将(powerset t)。更多细节:xs是一个累加器,它初始化为[]xxx::xs表示您将某物添加到现有的powerest xs。这里的xxx(h::t)::t,这是两个要加到xs头上的元素。(h::t)表示add head to tt表示(powerset t)中的每个元素。 < - 令人困惑的部分在于tt(powerset t)是列表中的其余部分,而其他t表示(powerset t)中的元素。

这里是fold功能的必要翻译:

let h::t = list 
let setfort = powerset t 
xs <- [] 
foreach s in setfort do 
    xs <- xs.add(t) // t is a valid subset of list 
    xs <- xs.add(h::t) // t with h is also a valid subset of list 
+0

感谢您对功能的说明,特别是易混淆的部分。它真的让我感到困惑! :) – Preets 2011-05-25 15:55:36