2013-04-29 20 views
1

我一直在試圖將一些C#到F#和尚未準備好,因爲我是比較新的F#如何將C#中的Parallel.Foreach轉換爲F#?

這裏是工作的C#代碼片段:

static void doParallelForeach() 
{ 
    // The sum of these elements is 40. 
    int[] input = { 4, 1, 6, 2, 9, 5, 10, 3 }; 
    int sum = 0; 

    Parallel.ForEach(
     input, 
     () => 0, 
     (n, loopState, localSum) => 
     { 
      localSum += n; 
      Console.WriteLine("Thread={0}, n={1}, localSum={2}", Thread.CurrentThread.ManagedThreadId, n, localSum); 
      return localSum; 
     }, 
     (localSum) => Interlocked.Add(ref sum, localSum) 
    ); 
} 

這裏是F#導致此編譯器錯誤的代碼片段:沒有重載符合方法「ForEach」。

let doParallelForeach = 

let input:int[] = [|4; 1; 6; 2; 9; 5; 10; 3|] 

let sum = 0 

Parallel.ForEach 

(
    input, 

    (fun()-> 0), 

    (fun (n, loopState, localSum) -> 
     localSum += n 
     Console.WriteLine("Thread={0}, n={1}, localSum={2}", Thread.CurrentThread.ManagedThreadId, n, localSum); 
     return localSum), 

    (fun (localSum) -> Interlocked.Add(ref sum, localSum)) 

) 

有人能解釋我在做什麼錯嗎?

+0

您是否嘗試過檢查列表或Seq iter /地圖? – Pacane 2013-04-29 20:22:53

回答

7

你的代碼有很多問題。這裏有一個直譯:

let doParallelForeach() = 
    let input:int[] = [|4; 1; 6; 2; 9; 5; 10; 3|] 
    let sum = ref 0 

    Parallel.ForEach (
      input, 
      (fun()-> 0), 
      (fun n loopState localSum-> 
       let localSum = localSum + n 
       Console.WriteLine("Thread={0}, n={1}, localSum={2}", Thread.CurrentThread.ManagedThreadId, n, localSum) 
       localSum), 
      (fun (localSum) -> Interlocked.Add(sum, localSum) |> ignore)) 

注:

  1. 因爲你的C#代碼使用的方法,我做了doParallelForeach成函數,而不是unit類型的值。
  2. return+=是無效的F#代碼。您不需要在F#中使用return,並且您只能修改可變值(即使此時也沒有複合賦值運算符)。相反,我們僅以localSum的影子創造新價值。
  3. 錯誤地使用了ref - 它是F#中的一個函數,不是修飾符,它用於定義新的引用值,而不是提取地址以傳遞給方法。此外,由於sum是一個不可改變的值,因此無論如何您都無法獲取它的地址。正確的方法是使用F#的ref函數使sumint ref類型的實例。
  4. 在F#中,定義委託時使用curried(而不是tupled)函數定義。也就是說,您使用fun n loopState localSum -> ...而不是fun (n, loopState, localSum) -> ...

需要注意的是,無論這些修補程序,這是一個奇怪的方法 - 將結果保存在未暴露過給調用者局部變量(sum)...

+0

感謝您的幫助。這確實清楚了一些事情。正如你所看到的,我仍然在學習繩索。是。這是奇怪的方法。我刪除了很多必要的代碼。 – guerillacodester 2013-04-29 20:48:03