2013-10-25 93 views
6

我期待學習F#,但有一點讓我感到困惑的是計算表達式(do-notation ??)語法和desugaring。Haskell程序員的計算表達式

在haskell中,您有一個非常簡單的Monad類型類和用於將綁定和返回的desugaring註釋的規則。添加關鍵字沒有任何魔力;唯一必須匹配的是類型。

在F#中有一堆構建器,關鍵字和複雜性。

對於如何將一個概念映射到另一個概念有很好的解釋嗎?

我基本上想知道我是如何映射

do 
    x <- monadicComputation 
    foo x 
    someOtherMonadicComputation 
    let y = somePureComputation x 
    return $ bar y 

到F#。

haskell中唯一的關鍵字是do,(< - )和let。

回答

13

您不能在F#中編寫通用單代碼,而必須通過命名與該表達式相關聯的構建器來指定您正在使用的monad。您的示例代碼如下所示:

let example = async { 
    let! a = someAsyncComputation 
    foo a 
    do! someOtherAsyncComputation 
    let y = somePureComputation a 
    return (bar y) 
} 

async計算表達式類型。在綁定monadic值時使用'bang'模式(do !, let!等),而常規關鍵字用於非單值數值。

let!對應於結合(>>=)let對應於letdo符號。 return對應於return,而return!用於產生現有的一元值。 do!類似於(>>),它爲其效果執行單值,而do用於非單點效果,在Haskell中沒有並行效果。

+1

我想你的意思是說'do!'與'(>>)'相似。 – MisterMetaphor

+0

@MisterMetaphor - 是的,謝謝。 – Lee

+0

我希望我能接受所有這些答案,但我會採取這一個,因爲看起來社區已經把它投得最多 – nimish

3

哈斯克爾做記號具有映射到bind功能只有一個特殊的語法,即<-,一切裏面做的只是正常的功能應用,其結果是單子類型,例如:returnputStr

同樣在F#中,您有let!來表示bind操作和return關鍵字語法糖(不像haskell中的正常函數調用,但此關鍵字映射到您定義的Return函數)。現在還有許多其他關鍵字您的計算表達式可以支持(如果不需要,可以輕鬆地忽略它們),它們全部記錄在here中。這些額外的操作可以爲您提供語法糖,以使用F#關鍵字而不是返回monadic值的正常函數。您可以看到,在F#計算表達式中可以重載的所有關鍵字都具有單值返回值。

所以基本上,您不必擔心所有這些關鍵字,只要將它們視爲正常的monad返回函數(具有可在文檔中找到的特定類型簽名),您可以使用F#關鍵字計算表達式語法。

4

如果您來自Haskell背景,那麼您最近可能會對我編寫的有關F#計算表達式的an academic article感興趣。

它將計算表達式語法(這非常靈活)鏈接到Haskell中使用的標準類型類。如前所述,F#不容易讓你編寫代碼通用於monad(它可以完成,但它不是慣用的),但另一方面它可以讓你選擇最合適的語法,你甚至可以得到很好的語法對於MonadPlus或單子變壓器。

除此之外,通過利中提到async單子,這裏是MonadPlus一個例子(使用序列表達 - 列表單子 - 作爲例子):

let duplicate list = seq { 
    for n in list do 
    yield n 
    yield n ∗ 10 } 

或者用於解析器的計算表達式:

let rec zeroOrMore p = parse { 
    return! oneOrMore p 
    return [] } 
+1

我發現這個答案太晚了,現在鏈接似乎被破壞了。您能否通過正確的鏈接更新您的答案? – Nicolocodev