可以在F#中约束抽象类型成员的输入参数吗?

时间:2012-11-10 20:35:56

标签: f#

考虑到本文Implementing phantom types in 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

1 个答案:

答案 0 :(得分:1)

如果您要问的是,您无法进一步约束特定成员的类类型参数。如果您愿意,可以引入一个独立约束的新成员类型参数。我不确定这是否能解决你的问题。

我认为Ascending和Descending都应该从HeapOrder继承而不是相反。

然后你可以使用Ascending或Descending实例化一个堆,并且'd应该捕获这个事实,这样你就不能与另一个具有不同HeapOrder的人合并。我不认为你需要单独限制合并。

以防万一,您可以通过将when放在最后来约束抽象成员的类型参数。你在最近两次合并中的'c'中也有一个拼写错误,'在c之后。

相关问题