Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# lambda expression without parameters

Tags:

lambda

f#

I'm newbie to F#, and I wanna use lambda expression without parameters. This works fine:

let a = fun () -> 2
a()

It returns 2.

But now I wanna it to return 6:

let a = 3* (fun () -> 2)
a()

But get an static error that function have too many arguments or can't be used in this context.

But this also works:

let a = 3* (fun _ -> 2) 4
a

Note that a now cannot be used as a function as a()

Can you explain this?

like image 786
dmitry Avatar asked Dec 19 '22 10:12

dmitry


2 Answers

Well, the expression fun() -> 2 is a function. Not a number, not a string, not an array of bytes, but a function. The only thing to do with a function is to call it. Or, in other words, execute it. Invoke it. That's what you do with a(). You pass it a parameter () (yes, two parentheses in a row is an actual thing in F#, you can pass it as a parameter), and the function runs and returns you a result. Which is 2. A number.

So, once again: first you have a function. Then you execute it. And the result of that execution is a number.

Now, if you want to multiply a function by three... What do you mean by that? That's kinda nonsensical. Do you mean for it to execute three times longer? Or return three results instead of one? Multiplying by a number is not something you can do with a function.

If you want another function that returns a 6 instead of 2, then just say so:

let a = fun() -> 2*3

Or, if you want to take your first function and build another function on top of it, by multiplying the result of the first function, - then you need to have this second function first call (invoke, execute) the first function, take its result, and multiply that by three:

let a = fun() -> 2
let b = fun() -> a() * 3

As for the very last example - that's a bit trickier.

First, the expression fun _ -> 2. That's also a function. And it takes one parameter. And it doesn't care what that parameter is. It sort of says "I'll take any parameter, whatever you throw at me, I don't care, I'll return you 2 anyway". So you can throw any parameter at it. For example, you can throw a 4 at it. It will take a 4, it's not proud. 4 is just fine. That's what you're doing by (fun _ -> 2) 4. This means "create a function that takes any parameter and returns 2, and execute that function with parameter 4".

You can express the same idea in a way that's a bit longer, but easier to understand:

let a = fun _ -> 2
let b = a 4   // b = 2

And then, as the last step, you take that result of executing the function with parameter 4, and multiply that result by 3. And you get 6. Which is a number. And not a function. So you can't execute (invoke, call) it anymore. Because, you know, you can't execute a number. Only a function.

like image 150
Fyodor Soikin Avatar answered Jan 12 '23 03:01

Fyodor Soikin


I understand. So if I want it to be expression, not a function, I need function to be invoked:

let a = 3* (fun () -> 2)()

so, here a=6

like image 45
dmitry Avatar answered Jan 12 '23 02:01

dmitry