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 继承,而不是相反。

然后你可以用 Ascending 或 Descending 实例化一个堆,并且 'd 应该捕获这个事实,这样你就不能与另一个具有不同 HeapOrder 的堆合并。我认为您不需要为此对 Merge 进行单独的约束。

以防万一,您可以通过将 when 放在末尾来限制抽象成员的类型参数。此外,在最后两次合并中,您的 'c 中有错字,' 位于 c 之后。

于 2012-11-12T19:38:01.923 回答