Raku Land

zef:CIAvash

# NAME

Curry - a Raku module for currying functions.

# DESCRIPTION

Curry is a Raku module for currying functions plus partially applying them.

# SYNOPSIS

```use Curry:auth<zef:CIAvash> :all;

# Curried subs
sub f (\$a, \$b) is curry {
\$a × \$b;
}
my &pf = f 2;
say pf 3;
=output 6␤

sub f2 (\$a, \$b, :\$c = 1) is curry {
[×] \$a, \$b, \$c;
}
my &pf2 = f 2, :c(4);
say pf 3;
=output 24␤

sub f3 (*@a) is curry {
[×] @a;
}
my &pf3 = f 2, 3;
say pf;
=output 6␤

say pf(4)();
=output 24␤

# Curried method and attribute
my class C {
has &.f is curry is rw;

method m (Int \$a, Int \$b) is curry {
\$a × \$b;
}
}
my C \$c .= new;
# Method
say \$c.m(2, 3)()
=output 6␤

my &pm = \$c.m(2, 3);
say pm;
=output 6␤

say pm(4)();
=output 24␤

# Attribute
\$c.f = * + *;
say \$c.f.(1, 2);
=output 3␤

my &pa = \$c.f.(1);
say pa 2;
=output 3␤

# Making Curry
my &f3 = Curry[* + *];
# Or
my &f4 = make_curry * + *;

my &cgrep = Curry[&grep];
# Or better
my &cgrep2 = new_curry &grep;

# Be careful with this
make_curry &grep;
# Or
make_curryable &grep; # This changes function's signature
# Original function (before being curried)
my &lost_grep = &grep.original_function;
```

# INSTALLATION

You need to have Raku and zef, then run:

``````zef install --/test "Curry:auth<zef:CIAvash>"
``````

or if you have cloned the repo:

``````zef install .
``````

# TESTING

``````prove -ve 'raku -I.' --ext rakutest
``````

# ROLES

## role Curry [Code:D \$function]

Curry role takes a function as parameter and does the `Callable` role

### method CALL-ME

```method CALL-ME(
|c
) returns Mu
```

Calls the function if all parameters are provided or returns a partially applied function

### method curry

```method curry(
|c
) returns Curry:D
```

Like `assuming` but returns a Curry. And tries to preserve the parameters of the partial function.

### method original_function

```method original_function() returns Code:D
```

Returns the original function, the function that was curried

## role Curry::CaptureAll

A role with a signature that captures all arguments

# SUBS

## multi sub make_curry

```multi sub make_curry(
Code:D \$f
) returns Curry:D is export(:all, :subs)
```

Takes a function, gives a cloned version of it to `Curry`, then adds the role to the function

## multi sub make_curry

```multi sub make_curry(
*@f where { ... }
) returns Array[Curry:D] is export(:all, :subs)
```

Takes functions, gives a cloned version of each to `Curry`, then adds the role to each function

## multi sub new_curry

```multi sub new_curry(
Code:D \$f
) returns Curry:D is export(:all, :subs)
```

Takes a function, creates a copy of it with role `Curry` mixed in

## multi sub new_curry

```multi sub new_curry(
*@f where { ... }
) returns Array[Curry:D] is export(:all, :subs)
```

Takes functions, creates a copy of each with role `Curry` mixed in

## multi sub make_curryable

```multi sub make_curryable(
Code:D \$f
) returns Curry:D is export(:all, :subs)
```

Takes a function and returns a curried function that does `Curry::CaptureAll`

## multi sub make_curryable

```multi sub make_curryable(
*@f where { ... }
) returns Array[Curry:D] is export(:all, :subs)
```

Takes functions and returns an array of curried functions that does `Curry::CaptureAll`

## multi sub trait_mod:

```multi sub trait_mod:<is>(
Sub:D \$sub,
:\$curry!
) returns Mu is export(:all, :traits)
```

`is curry` trait for `Sub`; Makes the function a curried function that does `Curry::CaptureAll`

## multi sub trait_mod:

```multi sub trait_mod:<is>(
Method:D \$method,
:\$curry!
) returns Mu is export(:all, :traits)
```

`is curry` trait for `Method`; Makes the function a curried function that does `Curry::CaptureAll`

## multi sub trait_mod:

```multi sub trait_mod:<is>(
Attribute:D \$attribute,
:\$curry!
) returns Mu is export(:all, :traits)
```

`is curry` trait for `Attribute`; Makes the function a curried function that does `Curry::CaptureAll`.

If you want to be able to set the function from outside of the class, you need to make the attribute writable with `is rw`. Setting the attribute with `new` doesn't work, only assignment works.

# REPOSITORY

https://github.com/CIAvash/Curry/

# BUG

https://github.com/CIAvash/Curry/issues