Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simple SRTP for method and property

Tags:

f#

I can't remember how to get SRTPs to work any more

I want a function that takes a param and calls a specified method, easy?

let inline YearDuck< ^a when ^a : (member Year : Unit -> string)>  (x : ^a) : string = 
    x.Year ()

but I get this

Severity    Code    Description Project File    Line    Suppression State
Error   FS0072  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 constrain the type of the object. This may allow the lookup to be resolved. 

it knows x is an ^a, I've specified ^a has method Year, so whats the problem?

(actually I want Year to be a property, but I thought i would walk before running)

like image 931
MrD at KookerellaLtd Avatar asked Sep 11 '25 08:09

MrD at KookerellaLtd


1 Answers

Try it this way instead:

let inline YearDuck x =
    (^a : (member Year : unit -> string) x)

Test code:

open System

type YearTest (dt : DateTime) =
    member _.Year() = string dt.Year

YearTest(DateTime.Now)
    |> YearDuck
    |> printfn "%A"   // "2022"

I wish I could say why it works this way and not the way you tried, but I really don't know, and I don't think it's clearly documented anywhere. SRTP is just dark magic in its current form.

If you want a property instead, try this:

let inline YearDuck x =
    (^a : (member get_Year : unit -> string) x)

type YearTest (dt : DateTime) =
    member _.Year = string dt.Year

YearTest(DateTime.Now)
    |> YearDuck
    |> printfn "%A"   // "2022"
like image 142
Brian Berns Avatar answered Sep 14 '25 00:09

Brian Berns