0
votes

Had this question answered and is somewhat similar but this question requires using Generics while enforcing parameter type to have some common fields.

type Document = {
    Name: string
    Version: string
}

let inline requestData<'t> (document: 't) =
    Console.WriteLine(document.Name)
    Console.WriteLine(document.Version)

Test

requestData<Document>({Name = "test"; Version="259723983"})

The error I'm getting is

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constraint the type of the object. This may allow the lookup to be resolved.

Edit

let inline requestData<'t> (document: 't) =
    let name = (^document: (member Name: string)(document))

The declared type parameter t' cannot be used here since the type parameter cannot be resolved at compile time.

1
requestData should work the same as with someComplexFun in the answer you linked - you just need to declare the statically resolved member access instead of calling document.Name directly - Honza Brestan

1 Answers

1
votes

You need to constrain on the type not the document parameter. Also, the 'T notation is for the usual generics, not SRTP. If you insist on adding the type parameter (not sure why), this is how you can define it:

let inline requestData< ^a when ^a : (member Name : string)  > x =
    Console.WriteLine(^a: (member Name: string)(x))

This way you can write this:

open System

type Document = {
    Name: string
    Version: string
}

type OtherDoc = {
    Name: string
    Version: string
}

let doc1 = {Document.Name = "Joe"; Version = "123"}
let doc2 = {OtherDoc.Name = "Jim"; Version = "456"}

requestData doc2
requestData doc1

Or:

requestData<Document> doc1 //Joe
requestData<OtherDoc> doc2 //Jim

This will be an error:

requestData<Document> doc2 //error FS0001: This expression was expected to have type...