Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function signature is different when it's part of a type (it's not generic anymore)

Tags:

f#

Why do the signatures of these functions differ?

This function:

type a () = 
    member this.ThirdElementOfTupleFromListToSequence = function 
        | (q, w, ids) -> (q,w, (List.toSeq ids))

has this signature: (obj * obj * obj list -> obj * obj * seq<obj>)

and when I assign the same function using let:

let ThirdElementOfTupleFromListToSequence = function 
    | (q, w, ids) -> (q,w, (List.toSeq ids))

it has this signature: ('a* 'b * 'c list -> 'a * 'b * seq<'c>)

both function aren't used anywhere.

like image 273
albertjan Avatar asked Sep 12 '13 09:09

albertjan


People also ask

What is the meaning of generic functions?

Typically a generic function is an instance of a class that inherits both from function and standard-object. Thus generic functions are both functions (that can be called with and applied to arguments) and ordinary objects.

What is generic data type?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What is generic data type in TypeScript?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.

How do I restrict a generic type in Java?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.


2 Answers

The problem here is that you are not defining a method, but a property whose value happens to be a function. And in .NET, properties cannot be generic.

In order to make it a method, you need to make it explicit in the declaration:

type a () =
    member this.ThirdElementOfTupleFromListToSequence(q, w, ids) =
        (q,w, (List.toSeq ids))

Or to make it more similar to your original version

type a () =
    member this.ThirdElementOfTupleFromListToSequence(arg) =
        match arg with
        | (q, w, ids) -> (q,w, (List.toSeq ids))

(Note that these two versions are actually different -- the first one is a method with three arguments, and the second one is a method with one argument which is a tuple).

like image 168
Tarmil Avatar answered Oct 15 '22 23:10

Tarmil


The reason the type signatures are different is because the CLR does not support generic properties; see: Why does C# not allow generic properties?

In your first example, the compiler infers the generic parameters just as it does for the let-bound example, but it has to "fill in" the generic parameters since it isn't allowed to create a generic property. The compiler uses obj in place of the generic parameters because that's guaranteed to work.

like image 34
Jack P. Avatar answered Oct 15 '22 22:10

Jack P.