Polymorphism with Generics and common fields

时光怂恿深爱的人放手 提交于 2019-12-13 03:36:06

问题


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:


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...


来源:https://stackoverflow.com/questions/49597987/polymorphism-with-generics-and-common-fields

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!