是否可以使用成员约束来创建类型缩写?


type FFRec<'state when 'state: (member Tape: Stack<unit -> unit>)
                   and 'state: (member Mem: ObjectPool)
                   and 'state: (member Str: CudaStream)
                   and 'state: (member Workspace: Workspace)
                   and 'state: (member IsInferenceOnly: bool)> =
    {
    W: d2M
    b: d2M
    a: d2M -> 'state -> d2M * 'state
    }

可以用接口替换所有这些成员约束,但这种方法的一个小问题是编译器不够聪明,无法意识到如果我有这样一个函数,例如:

let inline reluInitializer (state: ^state) (a: ^a)  =
    let scale = (1.0f / sqrt(addDims a |> float32))
    fillRandomUniformMatrix((str state),a,scale,0.0f)
    a

它不会意识到^state必须有一个接口约束,并且在记录泛型参数声明中给我一个无法解释的签名和实现差异错误。

如果可能的话,我宁愿使用成员约束而不是显式接口,但是我找不到使用类型缩写来缩短上述约束声明的方法。这在当前的f#中可能吗?

不能,不能在类型中使用静态解析的类型参数。

CLR不支持静态解析类型参数,因此需要在编译时擦除。这可以通过在调用处内联函数而不将其编译为IL来实现,但是类型必须具有IL表示,否则您无法在运行时拥有它的实例。

你应该考虑用评估函数的形式来表达你的约束,每个成员一个。这样,即使你的类型将编译一个"不可接受的"类型参数,它的用法也不会,因此有效地约束了整个程序。

至于你在例子中用^state参数描述的问题,我不太明白它是什么:你的函数没有任何成员访问,所以我不明白它如何导致与成员相关的错误。


并在评论中回答您的问题:不,在类型别名中包含成员约束以进行重用是不可能的。

最新更新