2

この投稿で説明されているファントムタイプのアイデアを取り入れて、F#でのファントムタイプの実装では、抽象型メンバー、より一般的には任意の型メンバーの入力パラメーターを制約しようとしています。これは不可能かもしれません、そして私はそのメッセージを受け取ってうれしいです。

これが私が試みていることです:

// my phantom type
type Ascending = interface end
type Descending = interface end
type HeapOrder =
    inherit Ascending
    inherit Descending

// my type
type IHeap<'a when 'a : comparison> =
    inherit System.Collections.IEnumerable
    inherit System.Collections.Generic.IEnumerable<'a>
...
abstract member Order : HeapOrder with get
...
// ...and one or the other of these inherited types :
type IHeap<'c, 'a when 'c :> IHeap<'c, 'a> and 'a : comparison> =
    inherit IHeap<'a>
// or:
type IHeap<'a, 'd when 'a : comparison  and 'd :> HeapOrder> =
    inherit System.Collections.IEnumerable
    inherit System.Collections.Generic.IEnumerable<'a>

type IHeap<'c, 'a, 'd when 'c :> IHeap<'c, 'a, 'd> and 'a : comparison and 'd :> HeapOrder> =
    inherit IHeap<'a>
...
// ...and the member I want to constrain, so that the HeapOrder of the 
// input parameter matches the HeapOrder of the instantiated type.
// Conceptually one of these alternatives (none of these build, 
// but they should convey what I'm attempting):
//
abstract member Merge : ('c when 'c<'c, 'a> : (member Order when Order :> 'd))
// or
abstract member Merge : ('c when c' :> IHeap<'c, 'a, 'd>) -> 'c
// or
abstract member Merge : ('c when c' : #IHeap<'c, 'a, 'd>) -> 'c
4

1 に答える 1

1

それがあなたが求めているものである場合、特定のメンバーのクラス型パラメーターをさらに制約することはできません。必要に応じて、独立して制約される新しいメンバータイプパラメーターを導入できます。それで問題が解決するかどうかはわかりません。

AscendingとDescendingはどちらも、その逆ではなく、HeapOrderから継承する必要があると思います。

次に、昇順または降順のいずれかでヒープをインスタンス化できます。'dはそのファクトをキャプチャする必要があるため、別のHeapOrderを持つ別のヒープとマージできません。そのためにMergeに個別の制約は必要ないと思います。

念のため、最後にwhenを付けることで、抽象メンバーの型パラメーターを制約できます。また、最後の2つのマージで'cにタイプミスがあり、'はcの後にあります。

于 2012-11-12T19:38:01.923 に答える