Why are functions associated with the first type they pass

I am new to F #. I was busy and I found something interesting, and I was hoping that someone could tell me what was going on behind the scenes.

So, I made a function: let my_func (x, y) = x + y .

Then I called the function with args 1 and 2 , giving me 3 . This is what I expected, but when I passed two lines to my_func , I got an error, although + is a valid statement with lines. I reworked my code, but this time called my_func with "cat" and " dog" , which gave me "cat dog" . Then I tried passing 1 and 2 back to my_func only to find that my_func not accepting long integers.

Why my_func behave this way?

let my_func (x, y) = x + y
my_func (1, 2) // produces => 3
my_func ("cat", " dog") // Error

restart program ...

let my_func (x, y) = x + y
my_func ("cat", " dog") // produces => "cat dog"
my_func (1, 2) // Error

+5
f #
Oct 31 '14 at 5:00 a.m.
source share
2 answers

@MarcinJuraszek showed you how to solve this problem, but said nothing about why this is happening.

You can think of it this way:

Type F # output works from top to bottom, from left to right - therefore, when the system tries to find the type for my_func , it will find the type assignment from the first line in which you use this function (the first example: int , and the second - string s). If you do not use it at all or do not define it in FSharp Interactive, it will be int by default.

Declaring a function as inline allows F # to use statically permitted type parameters (because of some details, this is possible only with an inline function), and then it really does something like duck input to find out from the declaration that functions need types, where the static + operator is defined in some way.

You can see this in the function type:

 val inline my_func : x: ^a * y: ^b -> ^c when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c) 

this rather complex type says exactly that:

There should be a static operator (+) : ^a * ^b -> ^c on ^a (think 'a ), which is used when you write + in the body of functions. As you can see, this is even more general than what you really need, but this is not a problem. F # will implement specific versions (with replaced generic types) for any use of this function (so in your example there will be two instances of my_func in your IL, one for int and one for string s) - but this will not hurt you during development .

So now you have a more general function that can be used with:

  • (+) : Int * Int -> Int on int
  • (+) : String * String -> String on string
+8
Oct 31 '14 at 5:14
source share

You must declare your method using the inline to make it work:

 let inline my_func (x,y) = x + y 

MSDN Details: Built-in Functions (F #)

+2
Oct 31 '14 at 5:04
source share



All Articles