1
votes

Given a function defined as let get<'T> var1 var2 : 'T option what type signature should the given to a record field that function will be assigned to?

I've tried various permutations of type MyType = {AFunc<'T> : obj -> obj -> 'T option} but but can't find any variant that lets me introduce the type argument.

I can do this type MyType = {AFunc: obj -> obj -> obj option} and that will let me create the record {AFunc = get} but then can't apply the function because the type argument is missing.

2

2 Answers

3
votes

There's a bit of ambiguity in your question. Do you want to be able to store get<'t> in a record for one particular 't per record, or do you want to have the record itself store a "generic" function like get<_>?

If the former, then TeaDrivenDev's answer will work.

If the latter, then there's no completely straightforward way to do it with F#'s type system: record fields cannot be generic values.

However, there's a reasonably clean workaround, which is to declare an interface type with a generic method and store an instance of the interface in your record, like this:

type OptionGetter = abstract Get<'t> : obj->obj->'t option
type MyType = { AFunc: OptionGetter }
let get<'t> var1 var2 : 't option = None // your real implementation here
let myRecord = { AFunc = { new OptionGetter with member this.Get v1 v2 = get v1 v2} }
let test : int Option = myRecord.AFunc.Get "test" 23.5
3
votes

You have to make the record type itself generic; only then will 'T be defined and usable.

type MyType<'T> = { AFunc : obj -> obj -> 'T option }