This question already exists:
Closed 12 years ago.
Possible Duplicate:
Functional programming: currying
I'm reading the free F# Wikibook here:
http://en.wikibooks.org/wiki/F_Sharp_Programming
There's a section explaining what Partial Functions are. It says that using F# you can partially use a function, but I just can't understand what's going on. Consider the following code snippet that is used an example:
#light
open System
let addTwoNumbers x y = x + y
let add5ToNumber = addTwoNumbers 5
Console.WriteLine(add5ToNumber 6)
The ouput is 11. But I'm not following. My function 'add5ToNumber' doesn't ask for a paramter so why can I invoke it and give it it one?
I really like learning about F# these days, baby steps!
Basically, every function in F# has one parameter and returns one value. That value can be of type unit, designated by (), which is similar in concept to void in some other languages.
When you have a function that appears to have more than one parameter, F# treats it as several functions, each with one parameter, that are then "curried" to come up with the result you want. So, in your example, you have:
let addTwoNumbers x y = x + y
That is really two different functions. One takes x and creates a new function that will add the value of x to the value of the new function's parameter. The new function takes the parameter y and returns an integer result.
So, addTwoNumbers 5 6 would indeed return 11. But, addTwoNumbers 5 is also syntactically valid and would return a function that adds 5 to its parameter. That is why add5ToNumber 6 is valid.
Currying is something like this:
addTwoNumbers is a function that takes a number and returns a function that takes a number that returns a number.
So addTwoNumbers 5 is in fact a function that takes a number and returns a number, which is how currying works. Since you assign addTwoNumbers 5 to add5ToNumber, that make add5ToNumber a function that takes a number an returns a number.
I don't know what type definition looks like in F# but in Haskell, the type definition of functions makes this clear:
addTwoNumbers :: (Num a) => a -> a -> a
On the other hand, if you wrote addTwonumbers to take a two tuple,
addTwoNumbers :: (Num a) => (a, a) -> a
then is would be a function that takes a two tuple and returns a number, so add5ToNumber would not be able to be created as you have it.
Just to add to the other answers, underneath the hood a closure is returned when you curry the function.
[Serializable]
internal class addToFive#12 : FSharpFunc<int, int>
{
// Fields
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated, DebuggerNonUserCode]
public int x;
// Methods
internal addToFive#12(int x)
{
this.x = x;
}
public override int Invoke(int y)
{
return Lexer.add(this.x, y);
}
}
This is known as eta-expansion : in a functional language,
let f a = g a
Is equivalent to
let f = g
This makes mathematical sense : if the two functions are equal for every input, then they're equal.
In your example, g is addTwoNumbers 5 and the code you wrote is entirely equivalent to:
let add5toNumber y = addTwoNumbers 5 y
There are a few situations where they are different:
In some situations, the type system may not recognize y as universally quantified if you omit it.
If addTwoNumbers 5 (with one parameter only) has a side-effect (such as printing 5 to the console) then the eta-expanded version would print 5 every time it's called while the eta-reduced version would print it when it's defined. This may also have performance consequences, if addTwoNumbers 5 involved heavy calculations that can be done only once.
Eta-reduction is not very friendly to labels and optional arguments (but they don't exist in F#, so that's fine).
And, of course, unless your new function name is extremely readable, providing the names of the omitted arguments is always a great help for the reader.
addTwoNumbers accepts 2 arguments (x and y).
add5ToNumber is assigned to the output of calling addTwoNumbers with only 1 argument, which results in another function that "saves" the first argument (x -> 5) and accepts one other argument (y).
When you pass 6 into add5ToNumber, its passing the saved x (5) and the given y (6) into addTwoNumbers, resulting in 11
Related
Now I understand that the first line of code can be shortened to the second one. This is the first time I'm running into it and I can't find any documentation on what the operator is called. Is it an abstract concept that can be used for other things as well?
let contains optValue value =
Option.exists (fun v -> v >= value) optValue
let contains optValue value =
Option.exists ((>=) value) optValue
You've already been told that the second example should have been (=) for your two functions to be equivalent, so I won't go over that. But I want to warn you that using the >= operator in this way might work differently than what you expect. The underlying reason has to do with how F# does partial application, and https://fsharpforfunandprofit.com/series/thinking-functionally.html is the best reference for that. (The relevant parts are the articles on currying and partial application, but you'll want to read the whole thing in order since later articles build on concepts explained in earlier articles).
Now, if you've read those articles, you know that F# allows partial application of functions: if you have a two-parameter function f a b, but you call it with just one parameter f a, the result is a function that is expecting a parameter b, and when it receives that, it executes f a b. When you wrap an operator in parentheses, F# treats it like a function, so when you do (>=) value, you get a function that's awaiting a second parameter x, and will then evaluate (>=) value x. And when F# evaluates (op) a b, whatever the operator is, it's the same as a op b, so (>=) value x is the same as value >= x.
And that's the bit that trips most people up at first. Because when you read Option.exists ((>=) value) optValue, you naturally want to read that as "Does the option contain something greater than or equal to value"? But in fact, it's actually saying "Does the option contain a value x such that value >= x is true?", i.e., something less than or equal to value.
So the simple rules of partial application, applied consistently, can lead to unexpected results with greater-than or less-than operators, or in fact any operator that isn't commutative. Be aware of this, and if you want to use partial application with non-commutative operators, double-check your logic.
This question already has answers here:
How to write a function for generic numbers?
(5 answers)
Closed 8 years ago.
I am writing an assembly with some functionality that is intended to work with numeric primitives, i.e. float, int, decimal, etc.
One of the functions takes two sequences and calculates the running average of the two. An implementation for floats may look like this
let average x y = (x+y)/2.
let a = [1..10] |> List.map float
let b = List.rev [1..10] |> List.map float
let result = (a, b) ||> List.map2 average
How can I make this generic for numeric primitives?
F# has so called "static member constraints" that can be used for writing generic numerical code. This is limited to F# (because .NET has no concept like this).
In general, you need to mark the function as inline. This will make the standard operators inside the function behave as generic. In addition, you need to avoid using constants (like 2.0). You can typically replace them with some operation from the LanguagePrimitives module. For example, your average function can be written as generic using:
let inline average x y =
LanguagePrimitives.DivideByInt (x + y) 2
For more information check out this blog post about generic numeric computations in F#.
I played around a little with F# today, wrote this:
let sq x = x * x
let i = sq 3
let d = sq 3.0
It compiles if I remove either the third or the fourth line, but not if both are present.
I get the error This expression should have type 'int', but has type 'float'.
The type inference works so that your function sq has type int -> int, because the first time compiler sees you use that function, you pass it an integer. So it assumes that sq is a function that takes an integer, and by definition of the function (x * x) it also returns an integer.
It is a bit complicated to define a fully generic arithmetic function in F#, but one way to do it is to make the function inline, like so:
let inline sq x = x * x
This way the body of your function will be inlined each time at the call site, so using an inlined sq function will be the same as substituting it's body every time it's used.
This approach has it's drawbacks, and I think it will be interesting for you to see this question.
Let-bound functions cannot be overloaded. In your specific case, you could use inline, which inlines the function body at compile time and can therefore choose an appropriate implementation of *, e.g.
let inline sq x = x * x
The other answers are correct but they leave out an important part of the jigsaw: the fact that in F# there are no implicit conversions between, for example, ints and floats. This is the reason why your second call is in effect calling a different, non existent, overload with a float argument.
The function let sq x = x * x on default has type int -> int.
If you put it in the context of a let d = sq 3.0, F# compiler will infer its type as float -> float.
In any way, this function can have only one type signature, either int->int, or float->float.
This is a limitation in how the bindings are implemented. There are 2 alternatives.
Firstly, add inline to the declaration.
Secondly, use member bindings in a class and override the different types.
These two are equivalent:
let f(x) =
10
let g = fun(x) ->
10
I think? They seem to do the same thing, but are there any cases where the behavior of the two would vary? I find the second version useful (even if more verbose) because you can use the <| and << operators to implement python-style decorator patterns; is there any case where I have to use the first version?
Furthermore, I fully understand how the second one works (the stuff on the right is just a function expression, which I dump into g) but how about the first one? Is there some compiler trick or special case that converts that syntax from a simple assignment statement into a function definition?
They are equivalent (modulo the 'value restriction', which allows functions, but not values, to be generic, see e.g. here).
As Brian already answered, the two are equivalent. Returning fun instead of declaring function using let makes difference if you want to do something (i.e. some initialization) before returning the function.
For example, if you wanted to create function that adds random number, you could write:
let f1 x =
let rnd = new System.Random()
x + rnd.Next()
let f2 =
let rnd = new System.Random()
fun y -> y + rnd.Next()
Here, the function f1 creates new Random instance every time it is executed, but f2 uses the same instance of rnd all the time (so f2 is better way of writing this). But if you return fun immediately, then the F# compiler optimizes the code and the two cases are the same.
I've just found something I'd call a quirk in F# and would like to know whether it's by design or by mistake and if it's by design, why is it so...
If you write any range expression where the first term is greater than the second term the returned sequence is empty. A look at reflector suggests this is by design, but I can't really find a reason why it would have to be so.
An example to reproduce it is:
[1..10] |> List.length
[10..1] |> List.length
The first will print out 10 while the second will print out 0.
Tests were made in F# CTP 1.9.6.2.
EDIT: thanks for suggesting expliciting the range, but there's still one case (which is what inspired me to ask this question) that won't be covered. What if A and B are variables and none is constantly greater than the other although they're always different?
Considering that the range expression does not seem to get optimized at compiled time anyway, is there any good reason for the code which determines the step (not explicitly specified) in case A and B are ints not to allow negative steps?
As suggested by other answers, you can do
[10 .. -1 .. 1] |> List.iter (printfn "%A")
e.g.
[start .. step .. stop]
Adam Wright - But you should be able
to change the binding for types you're
interested in to behave in any way you
like (including counting down if x >
y).
Taking Adam's suggestion into code:
let (..) a b =
if a < b then seq { a .. b }
else seq { a .. -1 .. b }
printfn "%A" (seq { 1 .. 10 })
printfn "%A" (seq { 10 .. 1 })
This works for int ranges. Have a look at the source code for (..): you may be able to use that to work over other types of ranges, but not sure how you would get the right value of -1 for your specific type.
What "should" happen is, of course, subjective. Normal range notation in my mind defines [x..y] as the set of all elements greater than or equal to x AND less than or equal to y; an empty set if y < x. In this case, we need to appeal to the F# spec.
Range expressions expr1 .. expr2 are evaluated as a call to the overloaded operator (..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr2) values, using an increment of 1. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
Range expressions expr1 .. expr2 .. expr3 are evaluated as a call to the overloaded operator (.. ..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr3) values, using an increment of expr2. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
The standard doesn't seem to define the .. operator (a least, that I can find). But you should be able to change the binding for types you're interested in to behave in any way you like (including counting down if x > y).
In haskell, you can write [10, 9 .. 1]. Perhaps it works the same in F# (I haven't tried it)?
edit:
It seems that the F# syntax is different, maybe something like [10..-1..1]
Ranges are generally expressed (in the languages and frameworks that support them) like this:
low_value <to> high_value
Can you give a good argument why a range ought to be able to be expressed differently? Since you were requesting a range from a higher number to a lower number does it not stand to reason that the resulting range would have no members?