2011-12-14 27 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#名單,他們一般都是有效的,除非你有特殊要求。