Search code examples
f#inline

How to transform OO calls into a some generic function calls


I have the following code

type Show<'a> =
    abstract member Show: 'a -> string

type Shows() = 
    member inline this.GetShow(x:string) = 
        {new Show<string> with member this.Show(x:string) = x}
    member inline this.GetShow(x:int) = 
        {new Show<int> with member this.Show(x:int) = sprintf "%A" x}

which works perfectly if I call it using normal OO notation.

printfn "100 %s" (Shows().GetShow("some").Show("some"))

However I'd like to wrap that into a function so that

let inline show x = (Shows().GetShow(x).Show(x))

But this gives me the following error

[FS0041] A unique overload for method 'GetShow' could not be determined based 
on type information prior to this program point. A type annotation may be 
needed. Candidates: 
member Shows.GetShow : x:int -> Show<int>, 
member Shows.GetShow : x:string -> Show<string>

Any ideas how to overcome this?


Solution

  • Does this get you close enough to what you want?

    let inline GetShow p x = (^x : (member GetShow : ^p -> ^o) (x, p))
    let inline Show p x = (^x : (member Show : ^p -> ^o) (x, p))
    
    let inline show x s = s |> GetShow x |> Show x
    
    Shows() |> show "a"
    Shows() |> show 1
    

    It's not too hard if you create your Shows outside of the inline function. This way the methods don't need to be inline.