2017-07-20 11 views
3

以下のタイプF#で型制約を持つジェネリック型の再帰的関係を表現できますか?

type WorkflowStep<'next, 'prev, 'cancel> = 
    abstract member Next : unit -> 'next 
    abstract member Prev : unit -> 'prev 
    abstract member Cancel : unit -> 'cancel 

を考えると、私は'next'prev'cancelもタイプWorkflowStepまたはタイプunitのでなければならないことのF#でタイプレベルにエンコードするために、この可能であるという事実を表現したいのですが?

答えて

5

、でも、一般的なようにタイプを必要としない、むしろ簡単なエンコードがあります:TransitionWorkflowStepへのためにあなたの要件をキャプチャ

type Transition = 
    | Step of WorkflowStep 
    | Done 

and WorkflowStep = 
    abstract member Next : unit -> Transition 
    abstract member Prev : unit -> Transition 
    abstract member Cancel : unit -> Transition 

別のステップまたは単位値を生成します。これにより、フロー制御のための逆CPSのような仕組みが得られます。

3

これはできません。これが実装されるとすれば、ワークフロー自体に無限のジェネリックのシーケンスが含まれていて、悲しいかなかf#でサポートされていないことを意味します。

上記のワークフロータイプの簡略化されたバージョンを使用する理由の詳細を説明します。

//error workflow must be provided a type 
type Workflow<'t when 't :> Workflow<_>> = 
    abstract member Next : unit -> 't 

しかし、我々はそれが今で適用される2つのパラメータを必要と返されたワークフローの型パラメータ を指定したとき。

//workflow now requires 2 parameters 
type Workflow<'nextvalue, 't when t:>Workflow<'nextvalue>> 
    abstract member Next : unit->'t 

Workflowクラスを作成するには、f#でサポートされていない無限の数の汎用引数が必要です。

これに代わる方法として、ワークフロータイプが1つのワークフローでしか動作しないように指定することもできます。あなたがいずれかの値を返すことができるように

type Workflow<'value> = 
    abstract member Next : unit -> Workflow<'value> option 
    abstract member Prev : unit -> Workflow<'value> option 
    abstract member Cancel : unit -> Workflow<'value> option 

あなたは上記を参照オプションタイプがある(一部)または単位(なし)

(注)この名前を持っていないタイプのリストの種類とそれが実装されますいくつかの言語は、variadic型と呼ばれます。あなたの説明は、それが実現不可能になるだろういくつかの詳細が欠落している場合を除き

関連する問題