说我有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的函数。
答案 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>()
,则必须禁用警告。