``` fun <T> foo(t: T){ val i: (T) -> ...
# announcements
r
Copy code
fun <T> foo(t: T){
    val i: (T) -> T = { it }
}
m
Copy code
inline fun <reified T> makeId() = { x: T -> x }
But it is not what I am looking for πŸ˜• I wanted something like Haskell
Copy code
id :: a -> a
id x = x
r
and what for? πŸ™‚ with type erasure in place I doubt that it is possible to escape a scope where T is actually known (or you lose type safety)
m
Copy code
inline fun <reified T> id() = { x: T -> x }

val double = { i: Int -> i * 2 }

infix fun <A, I, R> ((I)->R).after(f: (A)->I) = { a: A -> this(f(a)) }

fun main(args: Array<String>) {
    val f = double after id() after id() after double after double after id()
    print(f(1)) // 8
}
πŸ˜„
Close to perfect πŸ˜„
Perfect would be to do:
Copy code
val f = double after id after id after double after double after id
r
wait a minute πŸ˜„
m
More Heaskell-like version:
Copy code
inline fun <reified T> id() = { x: T -> x }
val double = { i: Int -> i * 2 }
operator fun <A, I, R> ((I)->R).times(f: (A)->I) = { a: A -> this(f(a)) }

fun main(args: Array<String>) {
    val f = double * id() * id() * double * double * id()
    print(f(1)) // 8
}
r
I think your problem here is, that Kotlin does not support currying as Haskell does
m
Currying is not a problem. Lack of generic function type is. From language design point of view it might be possible:
Copy code
val double = { i: Int -> i * 2 }
operator fun <A, I, R> ((I)->R).times(f: (A)->I) = { a: A -> this(f(a)) }
fun <T> id(x: T) = x

fun main(args: Array<String>) {
    val f = double * ::id * ::id * double * double * ::id
    print(f(1)) // 8
}
Or this:
Copy code
val double = { i: Int -> i * 2 }
operator fun <A, I, R> ((I)->R).times(f: (A)->I) = { a: A -> this(f(a)) }
val id = fun <T> (x: T) = x

fun main(args: Array<String>) {
    val f = double * id * id * double * double * id
    print(f(1)) // 8
}
But it is not. I think the reason is that it would be extremely hard to implement in Java which have really primitive support for generic
r
how does the definition look like in Haskell? Looks like function composition with partial application (or in other words currying)
nah... you do not even do a partial application. you only do composition. I guess it's a bug in the infix notation
If I am not mistaken, this does the same:
Copy code
fun <T> id(x: T) = x
fun <T, R, S> and(f: (T) -> R, g: (R) -> S): (T)-> S = {t -> g(f(t)) }
fun main(args: Array<String>) {
    val f = and(and(and(double, ::id), ::id), double)
    println(f(1))
}
oh... you made a mistake in your times function (unless you do not want function composition), the following works:
Copy code
val double = { i: Int -> i * 2 }
fun <T> id(x: T) = x
infix fun <T, R, S> ((T) -> R).and(g: (R) -> S): (T)-> S = {t -> g(this(t)) }
fun main(args: Array<String>) {
    val f = double and double and ::id and ::id and double
    println(f(1))
}
nah... it's not a mistake, more a limitation in type inference
in my version kotlin can infer the type because it works from left to right were we already know, that we have Int -> Int on the left. In your version it wants to apply T -> T first and does not know what type it should use πŸ˜„
m
You are right: If you rethink it, it is a problem with Kotlin type inference. This works:
Copy code
val double = { i: Int -> i * 2 }
fun <A, I, R> ((I)->R).after(f: (A)->I) = { a: A -> this(f(a)) }
fun <T> id(x: T) = x

fun main(args: Array<String>) {
    val intId: (Int)->Int = ::id
    val f = double.after(intId)
    print(f(1)) // 2
}
r
it's not the
::id
which fails but the
times
operator
m
Or even this:
Copy code
val double = { i: Int -> i * 2 }
fun <A, I, R> ((I)->R).after(f: (A)->I) = { a: A -> this(f(a)) }
fun <T> id(x: T) = x

fun main(args: Array<String>) {
    val f = double.after<Int, Int, Int>(::id)
    print(f(1)) // 2
}
r
I am not aware of the internal of their type inference algorithm but they could improve on this one. Questionable how much it would cost
m
Even this works:
Copy code
val double = { i: Int -> i * 2 }
infix fun <A, I, R> ((A) -> I).then(f: (I) -> R) = { a: A -> f(this(a)) }
fun <T> id(x: T) = x

fun main(args: Array<String>) {
    val f = double then ::id
    print(f(1)) // 2
}
r
that's the same as my and above yes, that's again left to right which Kotlin can grasp
I'll open a issue and see what they say
m
I've started writing
r
continue writing... I wanted to write I would not I will
m
I must say it is funny problem πŸ™‚ I am not at vacations but it was nice to check it out.
r
was nice looking into it πŸ™‚
m
πŸ‘ 1