2011-12-14 73 views
1

鉴于let ra = ResizeArray<int>()F#:Seq.forall怪异?

Seq.forall (fun i -> 
        let q = i % 2 
        if 0 = q then ra.Add i 
        true) <| seq { 1..10 } 

如果我这样做,ra.Count回报5

Seq.forall (fun i -> 
        let q = i % 2 
        if 0 = q then ra.Add i 
        0 = q) <| seq { 1..10 } 

如果我这样做,ra.Count回报0

那么,除非lambda函数的每次迭代都计算为true,否则实际上没有执行函数中的任何代码,或者什么?

这是怎么回事?

+8

引用[文档](http://msdn.microsoft.com/en-us/library/ee370522.aspx):“*如果任何应用程序返回”false“,那么总体结果为”false“,不再进一步元素进行测试。*“ – ildjarn 2011-12-14 20:12:11

+1

forall +副作用是一个糟糕的组合。 – 2011-12-14 21:02:33

+0

@MauricioScheffer取决于情况。在这种情况下(即简要地演示功能),它非常实用。 – MiloDC 2011-12-14 22:35:08

回答

5

您使用值“false”来停止Seq.forall函数处理其他元素。

由于1 % 2 = 0为假,因此会停止第一次迭代的评估。

1

下面的方法将更多的功能:

let (anyOdds, evens) = 
    seq {1..10} 
    |> Seq.fold (fun (anyOdds, xs) x -> 
     if x % 2 = 0 then 
      anyOdds, x :: xs 
     else true, xs) (false, []) 

手感舒适沟ResizeArray的支持F#名单,他们一般都是有效的,除非你有特殊要求。