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

时间:2016-09-06 10:55:18

标签: f# type-alias

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#中是否可能?

1 个答案:

答案 0 :(得分:4)

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

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

您应该考虑以评估员职能的形式表达您的约束,每个成员都有一个。这样,即使您的类型将使用&#34;不可接受的&#34;类型参数,它的用法不会被激活,从而有效地约束整个程序。

至于您在示例中使用^state参数描述的问题,我不太清楚它是什么:您的功能没有任何成员访问权限,所以我不知道#39;看看它会如何导致与会员相关的错误。

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