给定类型的更好的默认值

时间:2014-09-09 17:19:35

标签: f#

说我有DU

type Zero = Zero
type Succ<'a> = Succ of 'a

当我将值传递给仅使用该值类型的内联函数时,我可以使用Unchecked.defaultof<Zero Succ Succ>。但是,我将如何获得给定类型的正确值?一个不为空的。

由于Zero Succ Succ类型的唯一有效值为Succ(Succ(Zero)),我觉得我应该能够得到它。

我不关心中间类型的安全性,所以我可以使用类型转换。

我试过这个:

let rec makeProperSucc (a : Succ<'a>) = Succ(makeProperNum Unchecked.defaultof<'a>)

and makeProperNum (obj : obj) : obj = 
    if obj :? Zero then Zero :> obj
    else makeProperSucc (obj :?> Succ<obj>) :> obj

let instance<'a>() = makeProperNum Unchecked.defaultof<'a> :?> 'a

哪个不起作用,因为defaultof给我一个null并且所有类型信息都丢失了,因为我将它发送给期望obj的函数。

1 个答案:

答案 0 :(得分:3)

如何在DU中定义具有静态约束的静态成员?

这是一个快速草案,有一元操作员:

type Zero = Zero with
    static member (!!) Zero = Zero

type Succ<'a> = Succ of 'a with
    static member inline (!!) (Succ a) = Succ (!!a)

// Test
!!(Unchecked.defaultof<Succ<Succ<Succ<Zero>>>>)
// val it : Succ<Succ<Succ<Zero>>> = Succ (Succ (Succ Zero))

我使用运算符来保持简单,但您也可以手动编写静态约束,或者像inline helper中一样使用previous question

<强>更新

如果您想使用inline helper 1.x中使用的FsControl模块,您可以这样做:

type Instance = Instance with
    static member        instance(Instance, _:unit    ) = fun () -> ()
    static member        instance(Instance, _:Zero    ) = fun () -> Zero
    static member inline instance(Instance, _:Succ<'b>) = fun () -> 
        Succ (Inline.instance Instance ())

let inline instance() = Inline.instance Instance ()

let test:Succ<Succ<Zero>> = instance()

如果您想使用符号instance<'t>() ,则必须禁用警告。