F#: two ways of defining functions? - f#

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.

Related

Understanding F# value restriction

I'm learning F#. I'm here because I had something hard to understand about value restriction.
Here are the examples from the book I'm studying with.
let mapFirst = List.map fst
Since I had learned FP with haskell, I was pretty sure that this code would be well compiled, but it was not the case. It resulted error FS0030 (Sorry that I can't copy-paste fsi error message, since it was written in korean). Instead, I had to provide an explicit argument like:
let mapFirst inp = List.map fst inp // or inp |> List.map fst
But why? I thought that with the above example, compiler can surely infer the type of given value:
val mapFirst : ('a * 'b) list -> 'a list
If I remind correctly, I called this thing in haskell eta-conversion, and above two examples are entirely identical. (Maybe not entirely, though). Why should I privide parameters explicitly to the function can be curried without any loss of information?
I've understood that something like
let empties = Array.create 100 []
will not compile and why, but I don't think It has something to do with my question.
※ I took a look on this question, but it did not help.
This has to do with mutability.
Consider this snippet:
type T<'a> = { mutable x : 'a option }
let t = { x = None }
The type of t is T<'a> - that is, t is generic, it has a generic parameter 'a, meaning t.x can be of any type - whatever the consumer chooses.
Then, suppose in one part of the program you do:
t.x <- Some 42
Perfectly legitimate: when accessing t you choose 'a = int and then t.x : int option, so you can push Some 42 into it.
Then, suppose in another part of your program you do:
t.x <- Some "foo"
Oh noes, what happens now? Is t.x : int option or is it string option? If the compiler faithfully compiled your code, it would result in data corruption. So the compiler refuses, just in case.
Since in general the compiler can't really check if there is something mutable deep inside your type, it takes the safe route and rejects values (meaning "not functions") that are inferred to be generic.
Note that this applies to syntactic values, not logical ones. Even if your value is really a function, but isn't syntactically defined as such (i.e. lacks parameters), the value restriction still applies. As an illustration, consider this:
type T<'a> = { mutable x : 'a option }
let f t x =
t.x <- Some x
let g = f { x = None }
Here, even though g is really a function, the restriction works in exactly the same as with my first example above: every call to g tries to operate on the same generic value T<'a>
In some simpler cases the compiler can take a shortcut though. Thus, for example this line alone doesn't compile:
let f = List.map id
But these two lines do:
let f = List.map id
let x = f [1;2;3]
This is because the second line allows the compiler to infer that f : list int -> list int, so the generic parameter disappears, and everybody is happy.
In practice it turns out that this shortcut covers the vast majority of cases. The only time you really bump against the value restriction is when you try to export such generic value from the module.
In Haskell this whole situation doesn't happen, because Haskell doesn't admit mutation. Simple as that.
But then again, even though Haskell doesn't admit mutation, it kinda sorta does - via unsafePerformIO. And guess what - in that scenario you do risk bumping into the same problem. It's even mentioned in the documentation.
Except GHC doesn't refuse to compile it - after all, if you're using unsafePerformIO, you must know what you're doing. Right? :-)

SUMPRODUCT in F# without variables

I have already done some searches, and this question is a duplicate of another post. I am posting this just for future reference.
Is it possible to define SUMPRODUCT without explicitly using variable names x, y?
Original Function:
let SUMPRODUCT x y = List.map2 (*) x y |> List.sum
SUMPRODUCT [1;4] [3;25] // Result: 103
I was hoping to do this:
// CONTAINS ERROR!
let SUMPRODUCT = (List.map2 (*)) >> List.sum
// CONTAINS ERROR!
But F# comes back with an error.
I have already found the solution on another post, but if you have any suggestions please let me know. Thank you.
Function composition only works when the input function takes a single argument. However, in your example, the result of List.map2 (*) is a function that takes two separate arguments and so it cannot be easily composed with List.sum using >>.
There are various ways to work around this if you really want, but I would not do that. I think >> is nice in a few rare cases where it fits nicely, but trying to over-use it leads to unreadable mess.
In some functional languages, the core library defines helpers for turning function with two arguments into a function that takes a tuple and vice versa.
let uncurry f (x, y) = f x y
let curry f x y = f (x, y)
You could use those two to define your sumProduct like this:
let sumProduct = curry ((uncurry (List.map2 (*))) >> List.sum)
Now it is point-free and understanding it is a fun mental challenge, but for all practical purposes, nobody will be able to understand the code and it is also longer than your original explicit version:
let sumProduct x y = List.map2 (*) x y |> List.sum
According to this post:
What am I missing: is function composition with multiple arguments possible?
Sometimes "pointed" style code is better than "pointfree" style code, and there is no good way to unify the type difference of the original function to what I hope to achieve.

F# and lisp-like apply function

For starters, I'm a novice in functional programming and F#, therefore I don't know if it's possible to do such thing at all. So let's say we have this function:
let sum x y z = x + y + z
And for some reason, we want to invoke it using the elements from a list as an arguments. My first attempt was just to do it like this:
//Seq.fold (fun f arg -> f arg) sum [1;2;3]
let rec apply f args =
match args with
| h::hs -> apply (f h) hs
| [] -> f
...which doesn't compile. It seems impossible to determine type of the f with a static type system. There's identical question for Haskell and the only solution uses Data.Dynamic to outfox the type system. I think the closest analog to it in F# is Dynamitey, but I'm not sure if it fits. This code
let dynsum = Dynamitey.Dynamic.Curry(sum, System.Nullable<int>(3))
produces dynsum variable of type obj, and objects of this type cannot be invoked, furthermore sum is not a .NET Delegate.So the question is, how can this be done with/without that library in F#?
F# is a statically typed functional language and so the programming patterns that you use with F# are quite different than those that you'd use in LISP (and actually, they are also different from those you'd use in Haskell). So, working with functions in the way you suggested is not something that you'd do in normal F# programming.
If you had some scenario in mind for this function, then perhaps try asking about the original problem and someone will help you find an idiomatic F# approach!
That said, even though this is not recommended, you can implement the apply function using the powerful .NET reflection capabilities. This is slow and unsafe, but if is occasionally useful.
open Microsoft.FSharp.Reflection
let rec apply (f:obj) (args:obj list) =
let invokeFunc =
f.GetType().GetMethods()
|> Seq.find (fun m ->
m.Name = "Invoke" &&
m.GetParameters().Length = args.Length)
invokeFunc.Invoke(f, Array.ofSeq args)
The code looks at the runtime type of the function, finds Invoke method and calls it.
let sum x y z = x + y + z
let res = apply sum [1;2;3]
let resNum = int res
At the end, you need to convert the result to an int because this is not statically known.

What is currying in F#? [duplicate]

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

F# currying efficiency?

I have a function that looks as follows:
let isInSet setElems normalize p =
normalize p |> (Set.ofList setElems).Contains
This function can be used to quickly check whether an element is semantically part of some set; for example, to check if a file path belongs to an html file:
let getLowerExtension p = (Path.GetExtension p).ToLowerInvariant()
let isHtmlPath = isInSet [".htm"; ".html"; ".xhtml"] getLowerExtension
However, when I use a function such as the above, performance is poor since evaluation of the function body as written in "isInSet" seems to be delayed until all parameters are known - in particular, invariant bits such as (Set.ofList setElems).Contains are reevaluated each execution of isHtmlPath.
How can best I maintain F#'s succint, readable nature while still getting the more efficient behavior in which the set construction is preevaluated.
The above is just an example; I'm looking for a general approach that avoids bogging me down in implementation details - where possible I'd like to avoid being distracted by details such as the implementation's execution order since that's usually not important to me and kind of undermines a major selling point of functional programming.
As long as F# doesn't differentiate between pure and impure code, I doubt we'll see optimisations of that kind. You can, however, make the currying explicit.
let isInSet setElems =
let set = Set.ofList setElems
fun normalize p -> normalize p |> set.Contains
isHtmlSet will now call isInSet only once to obtain the closure, at the same time executing ofList.
The answer from Kha shows how to optimize the code manually by using closures directly. If this is a frequent pattern that you need to use often, it is also possible to define a higher-order function that constructs the efficient code from two functions - the first one that does pre-processing of some arguments and a second one which does the actual processing once it gets the remaining arguments.
The code would look like this:
let preProcess finit frun preInput =
let preRes = finit preInput
fun input -> frun preRes input
let f : string list -> ((string -> string) * string) -> bool =
preProcess
Set.ofList // Pre-processing of the first argument
(fun elemsSet (normalize, p) -> // Implements the actual work to be
normalize p |> elemsSet.Contains) // .. done once we get the last argument
It is a question whether this is more elegant though...
Another (crazy) idea is that you could use computation expressions for this. The definition of computation builder that allows you to do this is very non-standard (it is not something that people usually do with them and it isn't in any way related to monads or any other theory). However, it should be possible to write this:
type CurryBuilder() =
member x.Bind((), f:'a -> 'b) = f
member x.Return(a) = a
let curry = new CurryBuilder()
In the curry computation, you can use let! to denote that you want to take the next argument of the function (after evaluating the preceeding code):
let f : string list -> (string -> string) -> string -> bool = curry {
let! elems = ()
let elemsSet = Set.ofList elems
printf "elements converted"
let! normalize = ()
let! p = ()
printf "calling"
return normalize p |> elemsSet.Contains }
let ff = f [ "a"; "b"; "c" ] (fun s -> s.ToLower())
// Prints 'elements converted' here
ff "C"
ff "D"
// Prints 'calling' two times
Here are some resources with more information about computation expressions:
The usual way of using computation expressions is described in free sample chapter of my book: Chapter 12: Sequence Expressions and Alternative Workflows (PDF)
The example above uses some specifics of the translation which is in full detailes described in the F# specification (PDF)
#Kha's answer is spot on. F# cannot rewrite
// effects of g only after both x and y are passed
let f x y =
let xStuff = g x
h xStuff y
into
// effects of g once after x passed, returning new closure waiting on y
let f x =
let xStuff = g x
fun y -> h xStuff y
unless it knows that g has no effects, and in the .NET Framework today, it's usually impossible to reason about the effects of 99% of all expressions. Which means the programmer is still responsible for explicitly coding evaluation order as above.
Currying does not hurt. Currying sometimes introduces closures as well. They are usually efficient too.
refer to this question I asked before. You can use inline to boost performance if necessary.
However, your performance problem in the example is mainly due to your code:
normalize p |> (Set.ofList setElems).Contains
here you need to perform Set.ofList setElems even you curry it. It costs O(n log n) time.
You need to change the type of setElems to F# Set, not List now. Btw, for small set, using lists is faster than sets even for querying.

Resources