Reputation: 353
Curried functions in F#. I get the bit where passing in a subset of parameters yields a function with presets. I just wondered if passing all of the parameters is any different. For example:
let addTwo x y = x + y
let incr a = addTwo 1
let added = addTwo 2 2
incr
is a function taking one argument.
Is added
an int or a function? I can imagine an implementation where "added" is evaluated lazily only on use (like Schroedinger's Cat on opening the box). Is there any guarantee of when the addition is performed?
Upvotes: 17
Views: 2494
Reputation: 63772
No. But kind of yes. But really, no.
You can construct a pure functional language that only has functions and nothing else. Lambda calculus is a complete algebra, so the theory is there. In this model, added
can be considered a parameter-less function (in contrast to e.g. random()
, where there's one parameter of type unit).
But F# is different. Since it's a rather pragmatic mix of imperative and functional programming, the result is not a function[1]. Instead, it's a value, just like a local in C#. This is no implementation detail - it's actually part of the F# specification. This does have disadvantages - it means its possible to have an ambiguous definition, where a definition could be either a value or a function definition (14.6.1).
[1] - Though in a pure functional program, you can't tell the difference - it's the same as just doing a substitution of the function with a cached value, which is perfectly legal.
Upvotes: 2
Reputation: 233505
F# is an eagerly evaluated language, so an expression like addTwo 2 2
will immediately be evaluated to a value of the int
type.
Haskell, by contrast, is lazily evaluated. An expression like addTwo 2 2
will not be evaluated until the value is needed. The type of the expression would still be a single integer, though. Even so, such an expression is, despite its laziness, not regarded as a function; in Haskell, such an unevaluated expression is called a thunk. That basically just means 'an arbitrarily complex expression that's not yet evaluated'.
Upvotes: 13
Reputation: 564931
incr is a function taking one argument. Is added an int or a function?
added
, in this case, is a named binding that evaluates to an int. It is not a function.
I can imagine an implementation where "added" is evaluated lazily only on use (like Schroedinger's Cat on opening the box). Is there any guarantee of when the addition is performed?
The addition will be performed immediately when the binding is generated. There is no laziness involved.
As explained by TeaDrivenDev, you can change added
to be a bound function instead of a bound value by adding a parameter, which can be unit
:
let added () = addTwo 2 2
In this case, it will be a function, so the addition wouldn't happen until you call it:
let result = added () // Call the function, bind output to result
Upvotes: 12
Reputation: 6629
added
is not a function; it is just a value that is calculated and bound to the name on the spot. A function always needs at least one parameter; if there is nothing useful to pass, that would be the unit
value ()
:
let added () = addTwo 2 2
Upvotes: 18