rust: values, functions, currying, partial application and eta-reduction
In the previous post we talked about values, functions, currying, partial application and eta-reduction in haskell. This post shows how the same can be done in rust, be it not as nice.
values and functions
let a = 5;
Here the symbol a
is assigned with the value 5.
let a = 2 + 3;
Here the symbol a
is assigned with the result of calculating 2 + 3, which also is 5.
fn sum(x: i32, y: i32) -> i32 {
x + y
}
let a = sum(2, 3);
Here a function sum
is defined that takes two arguments and returns the sum of those two numbers.
The value a
is assigned to the result of calling sum
with arguments 2 and 3, which calculates 2 + 3, which is still 5.
currying
fn add_three(x: i32) -> i32 {
sum(3, x)
}
Here we define a new function add_three
that is defined as calling our earlier sum
function with 3 and x
.
Rust does not support partial application out of the box, so we need to rewrite our sum
function.
fn curried_sum(x: i32) -> impl Fn(i32) -> i32 {
move |y: i32| -> i32 {
x + y
}
}
let a = curried_sum(3)(2);
As you can see now partial application is possible for our new curried_sum
function.
fn add_three(x: i32) -> i32 {
curried_sum(3)(x)
}
let a = add_three(2);
Here we have rewritten add_three
using curried_sum
in curried form. This means that curried_sum
is first called with 3
as argument, and the result of that is a new
function that takes only one argument and we call that function with argument x
. In general calling a function with many arguments can be seen as calling that function with the first argument, then the result of that with the second argument, etc.
partial application
curried_sum(3)
is called a partial application of curried_sum
with 3
. The result of that partial application is a function that takes only one argument and returns that argument + 3.
eta-reduction
If you think about it, curried_sum(3)
is exactly what our add_three
function is supposed to do. Because of this we can simplify the definition with a process that is called eta-reduction.
let add_three = curried_sum(3);
let a = add_three(2);
Here we define a new name add_three
for the function curried_sum(3)
which is the function which takes one argument and returns that argument incremented by 3. As you can see, a
will still be 5.
// sum = (+)
This is not possible in rust as +
is not curried.
// addthree = (+ 3)
This is also not possible in rust, as +
is still not curried.
summary
It is definitely possible to use these concepts in rust, but it is not as nice as in haskell.
tags: haskell