Kotlin - How to recursively call a lambda function - recursion

I'm trying to re implement the linrec function from here in Kotlin. Here is what it currently looks like in Kotlin:
fun <A, B> linrec(indivisible: (List<A>) -> Boolean,
value: (List<A>) -> B,
divide: (List<A>) -> List<List<A>>,
combine: (A, B) -> B
) : (List<A>) -> B {
val myfunc: (List<A>) -> B = { input ->
if (indivisible(input)) {
value(input)
} else {
val split = divide(input)
val left = split[0][0]
val right = myfunc(split[1]) // Error
combine(left, right)
}
}
return myfunc
}
IntelliJ gives me the following errors, when I try to run the code:
Error:(40, 19) Kotlin: Unresolved reference: myfunc
My question is: How do I make a lambda function call itself?

You don't call a lambda ("anonymous function") from inside itself. That's what functions are for:
fun <A, B> linrec(indivisible: (List<A>) -> Boolean,
value: (List<A>) -> B,
divide: (List<A>) -> List<List<A>>,
combine: (A, A) -> B
) : (List<A>) -> B {
fun myfunc(input: List<A>): B { // rearranged things here
return if (indivisible(input)) { // added `return`
value(input)
} else {
val split = divide(input)
val left = split[0][0]
val right = myfunc(split[1])
combine(left, right) // *
}
}
return ::myfunc
}
Now this is exactly the code you've wrote, but it does not compile. On the line I marked with * kotlinc says Type mismatch: inferred type is B but A was expected.
P.S. I have no idea what that code is doing, so I only fixed the compilation error you've asked about.

Related

How to compose two async function in Rust

I am trying to write a higher order function that compose two async function.
i am basically looking for the async version this
fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
This my attempt so far.
fn compose_future<A, B, C, G, F>(f: F, g: G) -> (impl Fn(A) -> impl Future<C>)
where
F: Fn(A) -> impl Future<B>,
G: Fn(B) -> impl Future<C>,
{
move |x| async { g(f(x).await).await }
}
and i get the following error
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> src\channel.rs:13:17
|
13 | F: Fn(A) -> impl Future<B>,
| ^^^^^^^^^^^^^^
Is it possible to accomplish this ?
I'm not sure it is possible to do it that simple with impl Trait-s. The one solution I can come up with is old-fashioned future types usage without async-await feature. TLDR: full playground. Async-await uses a generators which internally holds a state machine, so we need to define it manually:
enum State<In, F, FutOutF, G, FutOutG> {
Initial(In, F, G), // Out composed type created
FirstAwait(FutOutF, G), // Composed type waits for the first future
SecondAwait(FutOutG), // and for the second
// here can be a `Completed` state, but it simpler
// to handle it with `Option<..>` in our future itself
}
Then define a composed type itself:
struct Compose<In, Out, F, FutOutF, G, FutOutG> {
state: Option<State<In, F, FutOutF, G, FutOutG>>,
_t: PhantomData<Out>,
}
// And "entry-point" would be something like that:
fn compose_fut<In, Out, F, FutOutF, G, FutOutG>(
i: In,
f: F,
g: G,
) -> Compose<In, Out, F, FutOutF, G, FutOutG> {
Compose {
state: Some(State::Initial(i, f, g)),
_t: PhantomData,
}
}
Then comes the most complex part - impl Future itself, here a base impl declaration without implementation:
impl<In, Mid, Out, F, FutOutF, G, FutOutG> Future for Compose<In, Out, F, FutOutF, G, FutOutG>
where
FutOutF: Future<Output = Mid>,
F: FnOnce(In) -> FutOutF,
FutOutG: Future<Output = Out>,
G: FnOnce(Mid) -> FutOutG,
{
type Output = Out;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// here comes the magic
}
}
Values transformed as following: In -> Mid -> Out, where F and G are our composed functions and their output are FutOutF and FutOutG accordingly. And finally Future::poll implementation:
let this = unsafe { self.get_unchecked_mut() };
let state = this.state.take();
match state {
None => Poll::Pending, // invalid state
Some(State::Initial(i, f, g)) => {
let fut = f(i);
this.state = Some(State::FirstAwait(fut, g));
cx.waker().wake_by_ref();
Poll::Pending
}
Some(State::FirstAwait(mut fut, g)) => {
let val = match unsafe { Pin::new_unchecked(&mut fut) }.poll(cx) {
Poll::Ready(v) => v,
Poll::Pending => {
this.state = Some(State::FirstAwait(fut, g));
return Poll::Pending;
}
};
let fut = g(val);
this.state = Some(State::SecondAwait(fut));
cx.waker().wake_by_ref();
Poll::Pending
}
Some(State::SecondAwait(mut fut)) => {
match unsafe { Pin::new_unchecked(&mut fut) }.poll(cx) {
Poll::Ready(v) => Poll::Ready(v),
Poll::Pending => {
this.state = Some(State::SecondAwait(fut));
Poll::Pending
}
}
}
}
I avoid any library to make it "plain", usually unsafe parts are handled with pin-project or futures::pin_mut. The state management is fairly complex, so I suggest to re-check the implementation, there might be mistakes.

Can I convert a Kotlin KFunction1 to a KFunction0 by applying the argument?

I have a reference to a functionthat needs a parameter.
fun foo(x: Int) = 2 * x
val f: KFunction1<Int, Int> = ::foo
Is there any way to write applyArgument where
val f2: KFunction0<Int> = f1.applyArgument(42)
assertEquals("foo", f2.name)
assertEquals(84, f2())
I don't want to use a callable reference, as I need access to the name property.
hope it helps you:
fun foo(x: Int) = 2 * x
val f1 = ::foo
val f0 = { -> f1(42) }
f0() //84
KFunctions are intented to represent functions that are explicitly decleared in Kotlin code, but f2 is not declared anywhere in the code. In addition KFunction has lot of reflection properties and functions which are not relevant to the applied function f2. Therefore even if it is possible it is not recommended.
If you want to do it anyway you can simply write an applyArgument function in this way:
fun <T, R> KFunction1<T, R>.applyArgument(value: T): KFunction0<R> {
return object : KFunction<R> by this, KFunction0<R> {
override fun invoke(): R {
return this#applyArgument(value)
}
}
}
But, if what you need is to preserve the name, I would do it in a safe way. One way could be:
data class Named<out T>(val name: String, val value: T)
fun <T, R> Named<T>.map(transform: (T) -> R): Named<R> = Named(name, transform(value))
val <F : KFunction<*>> F.named: Named<F>
get() = Named(name, this)
Then use it:
fun foo(x: Int) = 2 * x
val f: Named<(Int) -> Int> = ::foo.named
val f2: Named<() -> Int> = f.map { fValue -> { fValue(42) } }
assertEquals("foo", f2.name)
assertEquals(84, f2.value())
Partial application is possible.
You may just declare a function for partial application and use it for the :: reference.
Hence, the name would not be the original function. Another approach - create your own classes/interfaces
data class MyFunction1<T, R>(val name: String, val f: (T) -> R) {
operator fun invoke(t: T) = f(t)
}
data class MyFunction0<R>(val name: String, val f: () -> R) {
operator fun invoke() = f()
}
Now define the curring:
fun MyFunction1<T, R>.curry(t: T) = MyFunction0(name){ f(t) }
(it can be a member function too)

How do I create a macro that takes a function with multiple parameters and supplies the first argument for that function?

I want to be able to create a higher-order function (called g) that takes in a function (called f). g should pass in the first parameter to f and return a new function.
The use case is that I want to initiate a database connection in g and pass it functions that accept a database connection.
fn f1(a: i32, b: String) -> String {
b
}
fn f2(a: i32, c: i64, d: i16) -> i32 {
1000
}
fn g<T>(f: fn(a: i32, arbitrary_arguments_type) -> T) -> fn(arbitrary_arguments_type) -> T {
move |arbitrary_arguments| f(1, arbitrary_arguments)
}
fn main() {
g(f1)("hello".to_string());
g(f2)(10, 11);
}
How do I create a macro that takes in as an argument a function with a more than 1 parameter, where first parameter is of a certain type, and supplies that argument for that first function?
The specific question I'm having is how do I create a macro that takes in as an argument a function with a more than 1 parameter, where first parameter is of a certain type, supplies that argument for that first function.
Macros (even procedural macros) operate on syntax trees, so they can't change their behaviour based on semantics, including types and function arity. That means you'd have to have a different macro for each possible number of arguments. For example:
macro_rules! curry1 {
($func: ident, $($arg: expr),*) => {
|a| $func($($arg),*, a)
}
}
macro_rules! curry2 {
($func: ident, $($arg: expr),*) => {
|a, b| $func($($arg),*, a, b)
}
}
macro_rules! curry3 {
($func: ident, $($arg: expr),*) => {
|a, b, c| $func($($arg),*, a, b, c)
}
}
Which would be used like this:
fn f(a: i32, b: i32, c: i32) -> i32 {
a + b + c
}
fn main() {
// requires 2 extra args
let f_2 = curry2!(f, 2);
// requires 1 extra arg
let f_2_1 = curry1!(f, 2, 1);
println!("{}", f(2, 1, 3)); // 6
println!("{}", f_2(1, 3)); // 6
println!("{}", f_2_1(3)); // 6
}

Kotlin's reduce() function with different types

I was looking through array extension functions and found reduce() one
inline fun <S, T: S> Array<out T>.reduce(operation: (acc: S, T) -> S): S {
if (isEmpty())
throw UnsupportedOperationException("Empty array can't be reduced.")
var accumulator: S = this[0]
for (index in 1..lastIndex) {
accumulator = operation(accumulator, this[index])
}
return accumulator
}
here the accumulator variable of type S assigned with first element from the array with type T.
Can't wrap my head around the real use case of reduce() function with two data types. Here synthetic example which actually doesn't make any sense.
open class A(var width: Int = 0)
class B(width: Int) : A(width)
val array = arrayOf(A(7), A(4), A(1), A(4), A(3))
val res = array.reduce { acc, s -> B(acc.width + s.width) }
Seems most real life use cases with this function use this signature:
inline fun <T> Array<out T>.reduce(operation: (acc: T, T) -> T): T
Can you help with providing some examples, where reduce() function can be useful with different types.
Here is an example:
interface Expr {
val value: Int
}
class Single(override val value: Int): Expr
class Sum(val a: Expr, val b: Expr): Expr {
override val value: Int
get() = a.value + b.value
}
fun main(args: Array<String>) {
val arr = arrayOf(Single(1), Single(2), Single(3));
val result = arr.reduce<Expr, Single> { a, b -> Sum(a, b) }
println(result.value)
}

Most efficient way to fill a vector from back to front

I am trying to populate a vector with a sequence of values. In order to calculate the first value I need to calculate the second value, which depends on the third value etc etc.
let mut bxs = Vec::with_capacity(n);
for x in info {
let b = match bxs.last() {
Some(bx) => union(&bx, &x.bbox),
None => x.bbox.clone(),
};
bxs.push(b);
}
bxs.reverse();
Currently I just fill the vector front to back using v.push(x) and then reverse the vector using v.reverse(). Is there a way to do this in a single pass?
Is there a way to do this in a single pass?
If you don't mind adapting the vector, it's relatively easy.
struct RevVec<T> {
data: Vec<T>,
}
impl<T> RevVec<T> {
fn push_front(&mut self, t: T) { self.data.push(t); }
}
impl<T> Index<usize> for RevVec<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
&self.data[self.len() - index - 1]
}
}
impl<T> IndexMut<usize> for RevVec<T> {
fn index_mut(&mut self, index: usize) -> &mut T {
let len = self.len();
&mut self.data[len - index - 1]
}
}
The solution using unsafe is below. The unsafe version is slightly more than 2x as fast as the safe version using reverse(). The idea is to use Vec::with_capacity(usize) to allocate the vector, then use ptr::write(dst: *mut T, src: T) to write the elements into the vector back to front. offset(self, count: isize) -> *const T is used to calculate the offset into the vector.
extern crate time;
use std::fmt::Debug;
use std::ptr;
use time::PreciseTime;
fn scanl<T, F>(u : &Vec<T>, f : F) -> Vec<T>
where T : Clone,
F : Fn(&T, &T) -> T {
let mut v = Vec::with_capacity(u.len());
for x in u.iter().rev() {
let b = match v.last() {
None => (*x).clone(),
Some(y) => f(x, &y),
};
v.push(b);
}
v.reverse();
return v;
}
fn unsafe_scanl<T, F>(u : &Vec<T> , f : F) -> Vec<T>
where T : Clone + Debug,
F : Fn(&T, &T) -> T {
unsafe {
let mut v : Vec<T> = Vec::with_capacity(u.len());
let cap = v.capacity();
let p = v.as_mut_ptr();
match u.last() {
None => return v,
Some(x) => ptr::write(p.offset((u.len()-1) as isize), x.clone()),
};
for i in (0..u.len()-1).rev() {
ptr::write(p.offset(i as isize), f(v.get_unchecked(i+1), u.get_unchecked(i)));
}
Vec::set_len(&mut v, cap);
return v;
}
}
pub fn bench_scanl() {
let lo : u64 = 0;
let hi : u64 = 1000000;
let v : Vec<u64> = (lo..hi).collect();
let start = PreciseTime::now();
let u = scanl(&v, |x, y| x + y);
let end= PreciseTime::now();
println!("{:?}\n in {}", u.len(), start.to(end));
let start2 = PreciseTime::now();
let u = unsafe_scanl(&v, |x, y| x + y);
let end2 = PreciseTime::now();
println!("2){:?}\n in {}", u.len(), start2.to(end2));
}

Resources