F# let binding patterns - f#

The problem is not new in stackoverflow, but I am not able to comprehend the behavior of let binding with patterns and of the in keyword.
My textbook prefers the uncommon function definition format:
let foo = fun x -> let f = (fun x y -> x +y ) in f x
So that I translated in #light syntax:
let foo x =
let f y =
x + y
f x
If I set foo 4 it returns me 8. Why? I cannot comprehend what actually happens inside the function, even with the elegant explications from here. Why 4 becomes argument for both x and y?

You are defining a function inside another function, your inner function f captures a value from the outer function, the value x which is used in x + y so x becomes 4.
Then you call the inner function f x passing x to y which is also 4.
Another way to view it, without taking in account the specific value 4, your inner function is let f y = x + y but it's always called with x so y becomes x, then your function becomes something like let f a = a + a.
The key thing to understand this is that a function can capture a value from the context, in this case x.
So this explains the behavior of your function using the light syntax but you might be wondering why it differs from the one-liner version. It's because the translation is wrong. Here's the right translation:
let foo x =
let f x y =
x + y
f x
And now if you call it with foo 4 it returns a function that expect the other parameter.

Say we call the function foo with 4.
let foo x =
let f y =
x + y
f x
foo 4
We can replace foo 4 with the function foo replacing all the x with 4.
let f y =
4 + y
f 4
Now we can replace f 4 with the function f with y := 4.
4 + 4
Which is obviously 8.

Related

function with mutable arguments

in F#, it's not allowed to have mutable argument with functions. but if I have a function like the following:
let f x =
while x>0 do
printfn "%d" x
x <- x-1;;
when I compile this, I'm getting a compiler error.(not mutable)
How would I fix this function?
For pass-by-value semantics, you can use parameter shadowing.
Here, a shadowed (because it's the same name) mutable value x is declared on the stack.
let f x =
let mutable x = x
while x > 0 do
printfn "%d" x
x <- x - 1
For pass-by-reference semantics, you'll have to use a reference cell, which is a just a fancy way of passing an object which has a mutable field in it. It's similar to ref in C#:
let f x =
while !x > 0 do
printfn "%d" !x
x := !x - 1
Using a reference cell:
let x = (ref 10)
f x
Debug.Assert(!x = 0)
You could rewrite it like this:
let f x = [x.. -1..1] |> List.iter (printfn "%d")
If you want to keep the while loop, you could do this:
let f (x : byref<int>)=
while x>0 do
printfn "%d" x
x <- x-1
let mutable x = 5
f &x
Depends on whether you want the final, mutated value of x to be passed back to the caller of the function or mutate it only locally.
For local-only mutation, just declare another variable, which would be mutable, but initially will have the value of x:
let f x =
let mutable i = x
while i>0 do
printfn "%d" i
i <- i-1
For passing the result back to the caller, you can use a ref-cell:
let f (x: int ref) =
while x.Value>0 do
printfn "%d" x.Value
x := x.Value - 1
Note that now you have to refer to the ref-cell contents via the .Value property (or you can instead use operator !, as in x := !x - 1), and the mutation is now done via :=. Plus, the consumer of such function now has to create a ref-cell before passing it in:
let x = ref 5
f x
printfn "%d" x.Value // prints "0"
Having said that, I must point out that mutation is generally less reliable, more error-prone than pure values. The normal way to write "loops" in pure functional programming is via recursion:
let rec f x =
if x > 0 then
printf "%d" x
f (x-1)
Here, each call to f makes another call to f with the value of x decreased by 1. This will have the same effect as the loop, but now there is no mutation, which means easier debugging and testing.

F# Partially apply the second argument

in F# if I take a function that takes two arguments, for example, mod (%):
13 % 10
// val it : int = 3
which is the same as
(%) 13 10
// val it : int = 3
is there any way to write it in the pipe notation, currying the 13?
Obviously, the “two-argument function” is actually a one-argument function that returns an intermediate function. So can pipe
10 |> (%) 13
// val it : int = 3
However, I need the other way around, i.e. pipe the first argument 13, having the second argument 10 partially applied, but not the first one.
Is there anything in the language that helps to do that, without creating extra lambdas every time, i.e. to avoid the following?
13 |> (fun x -> x % 10)
There is no built-in, standard way to do this. Moreover, due to how function application works, it's impossible to do so: as soon as you write (%) 13, you've already applied the first argument, because function application has the highest and non-configurable precedence in F#.
You can, if course, make yourself a special function to produce a "weird" function application - one that would apply the second argument and leave a hole for the first:
let ap f x = fun y -> f y x
And then:
let x = 13 |> ap (%) 10
> x : int = 3
Incidentally, the function ap is a semi-standard occurrence in ML languages, and is usually called flip, because what it does is "flipping" the order of the arguments:
let flip f x y = f y x
Or, you can even make it into an operator:
let (-*-) = flip
And then:
let x = 13 |> (%) -*- 10
> x : int = 3
However, this sort of trickery gets unreadable very quickly. In practice, it is far more preferable to just declare a function that does what you need:
let mod10 x = x % 10
And then:
let x = 13 |> mod10
Or, if you really need it to be very general:
let mod' x y = y % x
And then:
let x = 13 |> mod' 10
You can write a combinator that will do this for any function of two arguments:
let inline flip f y x = f x y
This can be used as:
13 |> flip (%) 10
F# already contains an operator that will do what you want, namely <|:
10 |> (%) <| 13;;
val it : int = 10
This is equivalent to
(10 |> (%)) 13;;
val it : int = 10
K, you are looking for a flip
let flip f a b = f b a

Why are implicit parameters not considered compiler errors in F#

I am a bit new to functional programming, and while I am somewhat familiar with F#, I am still learning about all the strange ways it works.
//I love my Rice and Curry'd functions
let add x =
let subFunction y =
x + y
subFunction
//explicit parameter
let add1 y = add 1 y
//implicit parameter
let add10 = add 10
//calling it with the parameter it doesn't show that it takes
let twenty = add10 10
So here add10 has implicit parameters by the fact that it is calling a function that returns a function that takes a parameter. Why is it accepted that I can declare it that way instead of the same way I declared add1?
It is really deceptive as judging by its declaration it, one would assume its just an int.
That's something coming from lambda calculus called eta-reduction
Basically it means that you can simplify your function/lambda by eliminating the last parameter on both sides of the expression when they are the same:
// instead of
let f x y = x + y
// in F# you can write
let f x y = (+) x y
// which is also the same as
let f x y = ((+) x) y
// then you can remove y
let f x = (+) x
// and then remove x
let f = (+)
In F# you can play with this as long as you don't reach the value restriction. So in your code let add1 y = add 1 y and let add10 = add 10 are equivalent. This is an example of how can you apply logic to reason about your code, applied to refactoring.

Can't create generic partial application of a function in F#

I am looking for a way to fix this very certain situation: I have a function-factory toF that takes a function-parameter g and based on it creates a resulting function f
let toF g =
let f x = g x
f
let f = toF id
The problem is that I get a
error FS0030: Value restriction. The value 'f' has been inferred to have generic type val f : ('_a -> '_a) Either make the arguments to 'f' explicit or, if you do not intend for it to be generic, add a type annotation.
I can add type annotations (which I am not eager to do) or alternatively I can rewrite it like this:
let f' g x = g x
let f x = f' id x
I don't like doing it this way because if I do then every time I call f I am making another call to f' specifying g along the way. While the first example keeps g in the closure and requires just one call.
UPDATE (for Tomas)
I have tried what you suggested.
let toF g =
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f x = toF id x
let ``test``() =
1 |> f |> f |> ignore
What basically is happening is that every time I make a call to the function f it first calls toF id getting a composed function and only then calls that composed function on x.
Creating f using g
x: 1
Creating f using g
x: 1
So essentially the composition is created on every call to f via subsequent call to toF. But this is exactly what I was trying to avoid. By defining let f = toF id I was hoping to get a closure one sigle time and then be able to call it immediately. So the output I am expecting would be:
Creating f using g
x: 1
x: 1
UPDATE 2
The following doesn't work either for the very same reason:
let toF g =
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f() = toF id
let fg = f()
You just need to make f a syntactic function:
let toF g =
let f x = g x
f
let f x = toF id x
When f is not syntactically a function (taking parameter) but a value, you hit the "value restriction" error. I'm not going to try to explain it here, because there is already great info in previous posts like: Understanding F# Value Restriction Errors.
EDIT - If you want to make sure that g gets called only once (but still want the code to be generic) then the easiest way is to add unused unit parameter (to make it a function) and then call it once (which determines the generic parameters) and use the result multiple times:
let toF g =
let f x = g x
f
let f () = toF id
let fg = f ()
fg 1
fg 2
This is sadly needed, because having a function that is generic, but is returned by some computation would actually create a subtle hole in the type system - that's the reason for the "value restriction".
The easiest solution is to just add a type annotation. Assuming that there's only one real type you care about, this is completely straightforward:
let toF g =
let f x = g x
f
let f : _ -> int = toF id
If you really need to call f at different types, then you can wrap it in a generic type:
type F<'t>() =
static member val f : _ -> 't = toF id
let blah = F.f "blah"
let one = F.f 1

Value or constructor is not defined

I'm learning f# and I've got a pretty trivial problem that doesn't seem to make sense. I'm working on Project Euler problem 2 and I've got this:
let fib (x : BigInteger) (y : BigInteger) (max : BigInteger) =
let added = x + y
if added > max then y
else fib y (x + y) max
I've got the error at the recursive fib call:
Value or constructor 'fib' is not defined
And I'm not sure why. Any help?
Because fib is recursive function, it has to start with let rec.
In F#, if you want to write a recursive function, you have to use the rec keyword:
let rec fib (x : BigInteger) (y : BigInteger) (max : BigInteger) =
let added = x + y
if added > max then y
else fib y (x + y) max
That's because in F# under normal circumstances, you can only use identifiers declared before the current code, unlike in C#.
Talking of Project Euler Problem 2, you may consider instead of recursion going with Seq.unfold, which is very idiomatic and gives you all Fibonacci numbers at once:
let fibs = Seq.unfold (fun (current, next) ->
Some(current, (next, current + next))) (1,2)
Now fibs represents lazy sequence of Fibonacci numbers :
>fibs;;
val it : seq<int> = seq[1; 2; 3; 5; ...]
And to make it of BigInteger just substitute (1,2) by (1I,2I), although the solution allows you to stay within ordinary integers.

Resources