2013-10-25 24 views
6

私はF#を学びたいと思っていますが、私に混乱を招くことの1つは、計算式(表記法?)とdesugaringです。ハスケルプログラマの計算式

haskellでは、非常に単純なMonad typeclassと、バインドとリターンへのドゥーノーメイションの除外ルールがあります。キーワードの追加には魔法はありません。唯一のものは型が一致する必要があります。

F#には、ビルダーやキーワード、複雑さがたくさんあります。

あるコンセプトを他のコンセプトにどのようにマッピングするかについての良い説明はありますか?

私は基本的に私はF#2に

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

をマップする方法を知りたいです。

haskellの唯一のキーワードはdo、(< - )とletです。

答えて

13

F#で汎用モナドコードを書くことはできません。代わりに、式に関連付けられたビルダーに名前を付けることで、作業中のモナドを指定する必要があります。 async計算式タイプのため

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

:あなたのコード例は次のようになります。 'bang'パターン(do!、let!など)は、モナド値をバインドするときに使用され、通常のキーワードは非モナド値に使用されます。

let!letdo表記でletに対応している(>>=)結合に相当します。 returnreturnに対応し、return!は既存のモナド値を得るために使用される。 do!(>>)と似ていますが、doはモナドではないエフェクトであり、Haskellではパラレルではありません。

+1

「do!」は '(>>)'と似ています。 – MisterMetaphor

+0

@MisterMetaphor - はい、ありがたいです。 – Lee

+0

私はこれらすべての回答を受け入れることができれば幸いですが、コミュニティが最も多く投票したと思われるので、これを取るつもりです – nimish

3

Haskellは表記は他のすべてが内側にやる、bind関数にマップされている、すなわち<-一つだけの特別な構文を持ってやる例えば、結果はモナドのタイプであるため、通常の関数のアプリケーションです:returnputStrなど

F#でも同様に、bindの操作を表すlet!と、構文的な砂糖return(通常の関数呼び出しではなく、定義したReturn関数にマップされています)があります。計算式がサポートできる他の多くのキーワードがあります(必要でない場合は簡単に省略できます)。すべてがhereと記載されています。これらの追加操作は、モナドの値を返す通常の関数ではなく、F#キーワードを使用する構文的な砂糖を提供します。 F#の計算式でオーバーロードできるすべてのキーワードは、モナドの戻り値を持つことがわかります。

基本的に、これらすべてのキーワードについて心配する必要はなく、F#キーワードを使って呼び出すことができる正規のモナド関数(ドキュメントで見つけることができる特定のタイプシグネチャを持つ)と考えることができます計算式の構文

4

あなたが興味を持っているよりも、ハスケルの背景から来た場合an academic article私は最近、F#計算式について書きました。

これは、Haskellで使用されている標準タイプのクラスに非常に柔軟な演算式の構文をリンクします。すでに言及したように、F#はモナドに対して一般的なコードを簡単に書くことはできません(となりますが、それは慣用的ではありません)。一方、最も適切な構文を選択することができ、 MonadPlusまたはモナド変圧器の場合。

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

またはパーサーの計算式:リー言及しasyncモナドに加え

は、ここで(一例として - - リストモナド配列式を使用して)MonadPlusの一例です:

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

私はこの回答が遅すぎてリンクが壊れているようです。正しいリンクで回答を更新できますか? – Nicolocodev