限制参数类型

时间:2014-12-25 14:55:33

标签: f#

我正在尝试为条件检查引擎创建一个更紧凑的调用约定。工作示例代码是:

type MyType(s:string, i:int) =
    member val s = s with get, set
    member val i = i with get, set

let StringLenAtLeast10 =
    fun (s:string) -> s.Length >= 10  

let IntAtLeast10 =
    fun (i:int) -> i >= 10

let SelectS =
    fun (f:MyType) -> f.s

let SelectI =
    fun (f:MyType) -> f.i

type Condition1<'a>(f:'a->bool) =
    member this.IsSatisfied obj = f obj

let cond11 = new Condition1<MyType>(fun f -> StringLenAtLeast10 (SelectS f))
let cond12 = new Condition1<MyType>(fun f -> IntAtLeast10 (SelectI f))

我希望通过限制参数中间类型来改进它,如下所示:

type Condition2<'a>(selector:'a -> 'b, f:'b->bool) =
    member this.IsSatisfied obj = f (selector obj)

let cond21 = new Condition2<MyType>(SelectS, StringLenAtLeast10)
let cond22 = new Condition2<MyType>(SelectI, IntAtLeast10)

然而,这可能不起作用,可能是出于显而易见的原因。我想,一个。改进调用约定,是否可能,以及b。找出为什么它无法弄清楚类型关系?

/编辑: 正如kvb所指出的,必须明确指定所有类型参数。这就是无法在列表中对具有不同类型参数的条件进行分组的问题。所以相反,我利用了这样的类型系统:

type Condition<'a>(selector, checker) =
    member this.IsSatisfied (obj:'a) = (checker (selector obj)):bool

和类型干扰不允许使用像这样的条件

let cond = new Condition<MyType>(SelectS, IntAtLeast10)

因为它知道SelectS的输出不是IntAtLeast10的接受输入。

1 个答案:

答案 0 :(得分:3)

所有类型的类型参数在其定义中必须是显式的,因此您需要执行以下操作:

type Condition2<'a, 'b>(...) = ...

在通话网站上,您可以省略new关键字和显式参数,通常会推断出这些参数:

let cond21 = Condition2(SelectS, StringLenAtLeast10)