```"Curries a function, returning a function with two parameter
lists, given a function with at least one parameter. The
first parameter list of the returned function has just the
first parameter of the original function, and the second
parameter list has the remaining parameters.

That is, if `fun` has type `W(X,Y,Z)` then
`curry(fun)` has type `W(Y,Z)(X)`."
see (`function uncurry`, `function compose`)
tagged("Functions")
shared Return(*Rest) curry<Return,Argument,First,Rest>
(Return(*Tuple<Argument,First,Rest>) f)
(First first)
given First satisfies Argument
given Rest satisfies Argument[]
=> flatten((Rest args)
=> unflatten(f)(Tuple(first, args)));

"Uncurries a function, returning a function with one
parameter list, given a function with two parameter lists,
where the first parameter list has exactly one parameter.
The parameter list of the returned function has the
parameter of the first parameter list of the original
function, followed by all parameters of the second
parameter list.

That is, if `fun` has type `W(Y,Z)(X)` then `uncurry(fun)`
has type `W(X,Y,Z)`."
see (`function curry`, `function compose`)
tagged("Functions")
shared Return(*Tuple<Argument,First,Rest>)
uncurry<Return,Argument,First,Rest>
(Return(*Rest) f(First first))
given First satisfies Argument
given Rest satisfies Argument[]
=> flatten((Tuple<Argument,First,Rest> args)
=> unflatten(f(args.first))(args.rest));
```