Does rust support partial [application for] functions?

for example:

struct Test {
}

impl Test {
    pub fn test(&self, name:&str) -> String {
        name.to_string()
    }
}

fn main() {
    let test = Test {};
    println!("{}", (Test::test)(&test)("aaa"));
}

No, there’s no built-in partial application. (You can write “curry” as a higher-order function, but it’s not trivial to get the types right. These are not normal idioms in Rust.)

4 Likes

If a partial application is desired, it is usually done this way:

(|x| test.test(x))("aaa")
1 Like

Nit: Partial functions and partially applied functions are two different concepts.

4 Likes

I took the liberty to slightly edit the thread's title to clarify this ambiguity :slightly_smiling_face:


Here is what a currified version of Test::test would look like:

struct Test {}

impl Test {
    pub
    fn test (self: &'_ Test)
      -> impl '_ + FnOnce(&str) -> String
    {
        move /* self */ |name| {
            name.to_string()
        }
    }
}

fn main ()
{
    let test = Test {};
    println!("{}", Test::test (&test) ("aaa"));
    println!("{}", test.test () ("aaa")); // Also works.
}

If you have just one higher order function, you can do it with impl syntax:

fn add(a: u32) -> impl Fn(u32) -> u32 {
    move |b:u32| a + b
}

fn main() {
    let add2 = add(2);
    
    println!("{}", add2(3));
}

But if you have another level beyond that it seems you need to Box the returned Fn

The following works, and will soon be on stable Rust :slightly_smiling_face::

#![feature(min_type_alias_impl_trait)]

type Add2 = impl Fn(u32) -> Add1;
type Add1 = impl Fn(u32) -> u32;

fn add3 (x: u32)
  -> Add2
{
    move |y: u32| {
        move |z: u32| {
            x + y + z
        }
    }
}

fn main ()
{
    assert_eq!(6, add3 (1) (2) (3));
}
4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.