MrD at KookerellaLtd
MrD at KookerellaLtd

Reputation: 2795

explicitly declaring inline functions signatures

consider this code

open System.Runtime.CompilerServices


[<Extension>]
type Foo = 
    [<Extension>]
    static member inline classID (any : ^T) : ^U = 
        (^T : (member classID : Unit -> ^U) any)
    [<Extension>]
    static member inline parent (any : ^T) : ^U = 
        (^T : (member parent : Unit -> ^U) any)

let inline foo (tx : _) =
    tx.classID() + "!" + tx.parent().classID()

the first question is, what IS the signature of foo?

my intellisense says its

'a -> string (requires member classID and member parent and member classID)

which to be fair, is at best vague as there are 2 implicit type parameters involved here and it doesnt specify which type requires which member, but that may be a tooling issue.

Is it possible to write an explicit signature for this finction e.g. like this:

let bar : 'a -> string = 
    fun _ -> ""

i.e.

let [var] : [signature] = 
   fun [param] -> [result]

what would [signature] for foo?

(there will be an additional question about extracting this signature at run time, but I'll leave that as a seperate question)

Upvotes: 2

Views: 55

Answers (1)

Brian Berns
Brian Berns

Reputation: 17038

Here's how I would write foo with explicit type annotations:

let inline foo (tx : ^T
    when ^T : (member classID : unit -> string)
    and ^T : (member parent : unit -> ^U)
    and ^U : (member classID : unit -> string)) : string =
    tx.classID() + "!" + tx.parent().classID()

So, in theory, I suppose its signature is:

(^T
    when ^T : (member classID : unit -> string)
    and ^T : (member parent : unit -> ^U)
    and ^U : (member classID : unit -> string)) -> string

It's not possible to write an explicit signature for bar because bar would have to be inline, and only functions can be inline, so bar itself is impossible.

This is why I wrote "in theory" above. You can't use foo's signature in actual F# code, so does it really have a signature at all? The root problem here is that statically resolved type parameters in F# are (IMHO) very flaky and poorly documented, so it's hard to know for sure if there is any truly correct answer to your question.

Upvotes: 2

Related Questions