具有异常构造功能的F#类类型

时间:2018-06-26 23:21:39

标签: f#

我有一个这样定义的类类型:

type T1(?maybei1: int, ?maybei2: int) =

以下所有工作:

let t11 = T1(1, 2)
let t12 = T1(1)
let t13 = T1()

但是这个(没有预期):

let tuple = (1, 2)
let t14 = T1 tuple //error: expected int but given int * int
另一方面,如果我将类型定义为:

type T2(i1: int, i2: int) =

然后我可以用元组构造一个实例

let tuple = (1, 2)
let t24 = T2 tuple //ok

但是我丢失了可选项:

let t22 = T2(1) //error
let t23 = T2() //error

我尝试了其他构造函数:

type T3(?maybei1: int, ?maybei2: int) =
    new (i1: int, i2: int) = T3(i1, i2)

type T4(i1: int, i2: int) =
    new (?maybei1: int, ?maybei2: int) =

但是我没有一个可以同时使用可选参数和元组实例化的版本。 有什么想法(没有委派,封装或继承,只有一种类型)?

编辑

Tomas Petricek找到了使其工作的方法;足够好。

但是,正如他还提到的那样,恕我直言,有些事情听起来并不完全正确。 例如,如果没有使用元组的重载构造函数,我们最终会遇到以下情况:

let tup = (1, 2)

let t1 = T (1, 2) //ok
let t2 = T tup //error

在第一个实例化中,编译器将两个参数映射为构造函数所期望的选项类型,我希望在第二个实例化中也会发生相同的情况。 有谁知道不是这样的原因吗?

1 个答案:

答案 0 :(得分:8)

如果添加一个重载的构造函数,该构造函数将显式元组作为唯一参数,那么创建实例的所有方法都可以工作:

type T(?maybei1: int, ?maybei2: int) =
    new (tup:int*int) = T(fst tup, snd tup)
    member x.Values = maybei1, maybei2

T(1)
T(1, 2)
T(maybei2=2)
let tup = (1, 2)
T tup

老实说,我不完全确定将元组作为多个参数的方法的参数传递的规则是什么-这有些棘手。从逻辑上讲,您可以将成员视为一个元组,但是由于可选参数和编译(它作为常规方法进行编译),因此这还不是全部内容,因此行为有些微妙。但是,定义一个采用元组的显式重载(将编译为采用System.Tuple)就可以了!