2012-04-14 8 views
13

私はモナディの観測可能/反応性パーサーを定義しています。これは、連続したクエリであるため、通常のパーサとはまったく異なる動作をします。根本的なタイプは次のとおりです。単一ケースの識別ユニオンの目的

type Pattern<'a,'b> = Pattern of (IObservable<'a> -> IObservable<'b>) 

Iを意味:物事を定義するためのより適切な方法は、単一のケースが区別組合であるかのように関数型言語における様々なパーサの実装を見てから

IObservable<'a> -> IObservable<'b> 

が、それはそう

let find (Pattern p) = p 

質問は次のとおりです:これはちょうど慣例によるのか、それとも後での拡張の目的のためか、定義が決して変更されない場合でもこれを行う理由はありますか?

ボーナス質問:私はかなり方法この通って進めてきた、とケースどこを発見していない

type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b> 

:それはちょうどより便利なタイプの署名のためなら、なぜだけでなく、型の別名を使用します合成可能性は、DUを使用しないことによって影響を受ける。

答えて

14

F#コンパイラは、タイプの略語についての情報を保存していない、とだけではなく、意味論のための光抽象漏れの修正です。型シグネチャはプログラム仕様として理解できます。型チェッカーに自分の仕事をさせることは、プログラムの正確性を保証する良い方法です。複雑なプログラムをクリア型シグネチャで

type Vector = V of float * float 

// val add : Vector -> Vector -> Vector 
let add (V(x1, y1)) (V(x2, y2)) = V(x1 + y1, x2 + y2) 

:川下を使用して

type Vector = float * float 

// val add : float * float -> float * float -> Vector 
let add ((x1, y1): Vector) ((x2, y2): Vector): Vector = (x1 + y1, x2 + y2) 

が、それはあなたに透明性を与えるものではありません:

あなたはタイプの別名の場合には至る所型注釈を指定して明示的に必要とします実際に合成を維持しやすくします。

シングルケースのDUにさらに多くのケースを追加する方が簡単なだけでなく、メンバメソッドと静的メソッドでDUを拡張する方が簡単です。 1つの例は、しばしば、かなり印刷するためにToString()を上書きすることです。

+0

ありがとう、それは実際にはかなり具体的な理由です。間違いなく 'Pattern <'a,'b>'の代わりに 'IObservable <'a> - > IObservable <'b>'と入力したくないのです。 – yamen

+1

後にフォローアップする。私は組合に2番目のケースを追加することになり、したがって宇宙はバランスを取っています。 – yamen

0

私が理解しているように、単一ケースの区別されたユニオンタイプは、問題ドメインと意味的に関連する名前を、それ以外の汎用のバックエンドタイプの名前が 'string'である名前にします。

それはあなたがすべてで型推論の恩恵を受けないので、私の知る限り

+0

私はそれが本当だとは思わない。これがタイプエイリアスです。単一のケース識別された共用体は完全なクラスであり、この場合は関数をラップしています(またはC#のトークでデリゲートします)。実際に – yamen

+0

しかし、私はそれ以外の使用法を知らない...また、いくつかのメソッドを共用体型に追加できることに注意してください。 – nicolas

関連する問題