Marko Grdinić
Marko Grdinić

Reputation: 4062

Is it possible to make type abbreviations with member constraints?

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
    }

It is possible to replace all those member constraints with an interface, but a small problem with that approach is that the compiler is not smart enough to realize that if I have a function like this for example:

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

It won't realize that ^state will have to have an interface constraint and give me an inexplicable signature and implementation differ error in the record generic parameter declaration.

If it is at all possible I'd rather use member constraints than explicit interfaces, but I could not find a way to use type abbreviations to make the above constraint declarations shorter. Would that be possible in current F#?

Upvotes: 2

Views: 890

Answers (1)

Fyodor Soikin
Fyodor Soikin

Reputation: 80744

No, it is not possible to use statically resolved type parameters with types.

Statically resolved type parameters are not supported by the CLR, and therefore need to be erased at compile time. This is possible to do with a function by inlining it at the call site and not compiling it down to IL, but a type must have an IL representation, because otherwise you can't have instances of it at runtime.

You should consider expressing your constraints in the form of assessor functions, one for every member. This way, even though your type will compile with an "unacceptable" type argument, the usages of it won't, thus effectively constraining the whole program.

As for the problem you describe with the ^state parameter in your example, I don't quite see what it is: your function doesn't have any member access in it, so I don't see how it would cause an error related to members.


And responding to your question in the comments: no, it is not possible to include member constraints in a type alias for reuse.

Upvotes: 4

Related Questions