Why are implicit parameters not considered compiler errors in F# - 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.

Related

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

F# let binding patterns

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.

Confusing anonymous function construct

I'm reading through an F# tutorial, and ran into an example of syntax that I don't understand. The link to the page I'm reading is at the bottom. Here's the example from that page:
let rec quicksort2 = function
| [] -> []
| first::rest ->
let smaller,larger = List.partition ((>=) first) rest
List.concat [quicksort2 smaller; [first]; quicksort2 larger]
// test code
printfn "%A" (quicksort2 [1;5;23;18;9;1;3])
The part I don't understand is this: ((>=) first). What exactly is this? For contrast, this is an example from the MSDN documentation for List.partition:
let list1 = [ 1 .. 10 ]
let listEven, listOdd = List.partition (fun elem -> elem % 2 = 0) list1
printfn "Evens: %A\nOdds: %A" listEven listOdd
The first parameter (is this the right terminology?) to List.partition is obviously an anonymous function. I rewrote the line in question as this:
let smaller,larger = List.partition (fun e -> first >= e) rest
and it works the same as the example above. I just don't understand how this construct accomplishes the same thing: ((>=) first)
http://fsharpforfunandprofit.com/posts/fvsc-quicksort/
That's roughly the same thing as infix notation vs prefix notation
Operator are functions too and follow the same rule (ie. they can be partially applied)
So here (>=) first is the operator >= with first already applied as "first" operand, and gives back a function waiting for the second operand of the operator as you noticed when rewriting that line.
This construct combines two features: operator call with prefix notation and partial function application.
First, let's look at calling operators with prefix notation.
let x = a + b
The above code calls operator + with two arguments, a and b. Since this is a functional language, everything is a function, including operators, including operator +. It's just that operators have this funny call syntax, where you put the function between the arguments instead of in front of them. But you can still treat the operator just as any other normal function. To do that, you need to enclose it on parentheses:
let x = (+) a b // same thing as a + b.
And when I say "as any other function", I totally mean it:
let f = (+)
let x = f a b // still same thing.
Next, let's look at partial function application. Consider this function:
let f x y = x + y
We can call it and get a number in return:
let a = f 5 6 // a = 11
But we can also "almost" call it by supplying only one of two arguments:
let a = f 5 // a is a function
let b = a 6 // b = 11
The result of such "almost call" (technically called "partial application") is another function that still expects the remaining arguments.
And now, let's combine the two:
let a = (+) 5 // a is a function
let b = a 6 // b = 11
In general, one can write the following equivalency:
(+) x === fun y -> x + y
Or, similarly, for your specific case:
(>=) first === fun y -> first >= y

Creating a negated predicate in F#

I have a predicate in F# for example
let myFunc x y = x < y
Is there a way to create the negated version of this function?
So something that would be functionally similar to
let otherFunc x y = x >= y
But by using the original myFunc?
let otherFunc = !myFunc // not valid
What you are trying to do is called "function composition". Check out the function composition operator of f#:
In F# what does the >> operator mean?
I don't have a compiler available to experiment, but you could start from
let otherFunc = myFunc >> not
and work your way through errors.
EDIT: Max Malook points out that this will not work with the current definition of myFunc, because it takes two arguments (in a sense, this is functional-land). So, in order to make this work, myFunc would need to change into accepting a Tuple:
let myFunc (a, b) = a > b
let otherFunc = myFunc >> not
let what = otherFunc (3, 4)
Negation in F# is done with the function not. The ! operator is for dereferencing ref cells.
let otherFunc x y = not (myFunc x y)

Different functions definition in F# [duplicate]

This question already has answers here:
F# Functions vs. Values
(4 answers)
Closed 8 years ago.
Newby question f# related,
What is the difference between this definitions in f# ?
module s
let log p =
printfn "expression is %A" p
let loggedWorkflow =
let x = 42
log x
let y = 43
log y
let z = x + y
log z
z
s.loggedWorkflow
and this one
module s
let log p =
printfn "expression is %A" p
let loggedWorkflow() =
let x = 42
log x
let y = 43
log y
let z = x + y
log z
z
s.loggedWorkflow()
The first one does not call the inner log, only returns z value
Why it works this way?
Thanks :)
I take this sample from
http://fsharpforfunandprofit.com/posts/computation-expressions-intro/
let loggedWorkflow = ... is defining a value. The body is evaluated as soon as the definition is reached (typically when the module s is loaded), and the value of loggedWorkflow is remembered as the result of evaluating the body, and returned every time someone evaluates s.loggedWorkflow.
let loggedWorkflow() = ... is defining a function that takes a single argument of type unit - the only value of this type is (), also typically pronounced "unit". The body doesn't get evaluated straight away, but only when the function is actually called. Each time it is called by actually passing an argument of type unit, e.g. with s.loggedWorkflow(), the body is evaluated and the resulting value returned.

Resources