2010-10-14 39 views
3

計算方法中Run()方法的狀態是什麼?我已經在幾個例子中看到了它(here,here,here),並且我已經看到它是F#的編譯器源代碼,但它不在specMSDN documentation中。我就此提交了一份issue in MS Connect,並且在沒有進一步解釋的情況下被封爲「通過設計」。計算表達式中的運行方法

那麼它是不推薦/無證/不受支持?我應該避免它嗎?

UPDATE:MS連接問題狀態被及時改變和更新,包括運行()

+0

在我的博客中,我是F#的新手。我對Run()等高級概念的使用可能不一定代表最佳實踐。當我剛剛學習時,我傾向於探索語言構造的奇怪和非典型用法,哈哈。 – TechNeilogy 2010-10-15 02:10:28

回答

8

6.3.10計算表達式

更具體地說,計算 表達式形式的MSDN頁 builder-expr {cexpr}其中cexpr是, 在句法上, 表達式的語法與在comp-expr中定義的附加 結構。 計算表達式用於 序列和其他非標準 解釋F#表達式 語法。表達式生成器-EXPR { cexpr}轉換爲

let b = builder-expr in b.Run (b.Delay(fun() -> {| cexpr |}C)) 

用於新鮮變量b。如果在檢測到此 表達式時,如果b的推斷類型上沒有方法Run,則該調用將被省略。同樣,如果沒有一種方法延遲存在於>當這個表達式檢查B的類型,則該調用將省略

+0

謝謝,我完全錯過了 – 2010-10-14 20:38:49

4

我認爲,在發展過程中比較晚加入Run方法,所以這可能是一個原因爲什麼它在文檔中缺失。正如desco解釋的那樣,該方法用於「運行」計算表達式。這意味着無論您何時寫expr { ... },翻譯後的代碼將被包裝在Run的調用中。

該方法有點問題,因爲它打破了組合性。例如,它是明智的要求是,對於任何計算表達式,下面的兩個實施例表示相同的事情:

expr { let! a = foo()   expr { let! c = expr { 
     let! b = bar(a)     let! a = foo() 
     let! c = woo(b)     let! b = bar(a) 
     return! zoo(c) }     return! woo(b) } 
             return! zoo(c) } 

然而,Run方法將只對總體結果在左例和兩次稱爲在右邊(用於整體計算表達式和嵌套的表達式)。該方法的常用類型簽名是M<T> -> T,這意味着正確的代碼將不會編譯。

出於這個原因,它是在創建時單子(因爲它們通常被定義並在Haskell例如使用),這是因爲Run方法打破單子的一些很好的方面,以避免它是個好主意。但是,如果你知道你在做什麼,那麼它可能是有用的...

例如,在我的break代碼,計算建設者立即執行它的身體(在聲明),因此增加Run解開結果不會破壞組合性 - 組成意味着只是運行另一個代碼。然而,定義Runasync和其他延遲計算根本不是一個好主意。

+0

嗯,這是令人擔憂的......我實際上使用它來啓用組合性(代碼:http://github.com/mausch/FsSql/blob/938b55f7e057e95d10de2cca6f4f2679c870cc2e/FsSql/Transactions。 fs#L120) – 2010-10-14 21:47:05

+0

@Mauricio:我不完全瞭解你的代碼,但一個重要的區別是你的'Run'有一個'M - > M ' - 破壞兼容性的情況通常有'M - > T'(例如,計算構建器創建任務並啓動它時)。 – 2010-10-14 23:05:06