Size: a a a

Kotlin Community

2020 June 01

ch

central hardware in Kotlin Community
И не будет
источник

AN

Alexander Nozik in Kotlin Community
Phoenix
Мне кажется я исчерпал свой лимит вопросов на сегодня, но всё же. Есть какие-нибудь костыли для реализации экстеншн функций с двумя получателями, кроме наследования?
Keep-176
источник

AN

Alexander Nozik in Kotlin Community
central hardware
И не будет
Посмоооотрим
источник

AN

Alexander Nozik in Kotlin Community
Phoenix
Мне кажется я исчерпал свой лимит вопросов на сегодня, но всё же. Есть какие-нибудь костыли для реализации экстеншн функций с двумя получателями, кроме наследования?
Костыль есть -  делается класс обертка и там мембер экстеншен
источник

AL

Alexander Levin in Kotlin Community
Phoenix
Мне кажется я исчерпал свой лимит вопросов на сегодня, но всё же. Есть какие-нибудь костыли для реализации экстеншн функций с двумя получателями, кроме наследования?
Скорее нет, чем да. Т.е. есть два обходных пути:
1. Экстеншн функция лежит в одном из нужных классов (class A { fun B.foo() { } })
2. Очень хитро создавать контексты, чтобы создавать композитный контекст, который отнаследуется от двух обычных

Но да, прямое решение проблемы - KEEP-176.
источник

AN

Alexander Nozik in Kotlin Community
Alexander Levin
Скорее нет, чем да. Т.е. есть два обходных пути:
1. Экстеншн функция лежит в одном из нужных классов (class A { fun B.foo() { } })
2. Очень хитро создавать контексты, чтобы создавать композитный контекст, который отнаследуется от двух обычных

Но да, прямое решение проблемы - KEEP-176.
Можно еще делать вложенные контексты, но это не решает проблему сигнатуры функции с двумя экстеншенами
источник

P

Phoenix in Kotlin Community
Alexander Nozik
Костыль есть -  делается класс обертка и там мембер экстеншен
а если оба класса нельзя менять? если я правильно понял
источник

P

Phoenix in Kotlin Community
Alexander Levin
Скорее нет, чем да. Т.е. есть два обходных пути:
1. Экстеншн функция лежит в одном из нужных классов (class A { fun B.foo() { } })
2. Очень хитро создавать контексты, чтобы создавать композитный контекст, который отнаследуется от двух обычных

Но да, прямое решение проблемы - KEEP-176.
что под контекстами имеется ввиду?
источник

AN

Alexander Nozik in Kotlin Community
Phoenix
а если оба класса нельзя менять? если я правильно понял
Тогда никак. Только делать обертки.
источник

AA

Andrey Antipov in Kotlin Community
Есть ещё каррирование екстеншен лямбд. Что-то типа:
fun String.foo(): Double.() -> Int.() -> String = dbl@ { { "${this@foo} ${this@dbl} $this" } }
fun main() {
   println("bar".foo().let { 2.0.it() }.let { 1.it() })
   println("baz".foo()(3.2)(2))
}
источник

AL

Alexander Levin in Kotlin Community
Phoenix
что под контекстами имеется ввиду?
Ну в общем случае просто класс.

Идея очень грубо такая (могу местами наврать, но суть вроде похожа)

interface A //and some impl
interface B //and some impl
class Composite(val a: A, val b: B): A by a, B by b

fun A.withCompositeContext(B b, action: Composite.() -> Unit) = Composite(this, b).run(::action)

Тогда экстеншны можно навешивать на композитный тип
источник

P

Phoenix in Kotlin Community
Alexander Levin
Ну в общем случае просто класс.

Идея очень грубо такая (могу местами наврать, но суть вроде похожа)

interface A //and some impl
interface B //and some impl
class Composite(val a: A, val b: B): A by a, B by b

fun A.withCompositeContext(B b, action: Composite.() -> Unit) = Composite(this, b).run(::action)

Тогда экстеншны можно навешивать на композитный тип
Выглядит круто, поиграюсь, спасиб
источник

P

Phoenix in Kotlin Community
Andrey Antipov
Есть ещё каррирование екстеншен лямбд. Что-то типа:
fun String.foo(): Double.() -> Int.() -> String = dbl@ { { "${this@foo} ${this@dbl} $this" } }
fun main() {
   println("bar".foo().let { 2.0.it() }.let { 1.it() })
   println("baz".foo()(3.2)(2))
}
выглядит чуть жутковато
источник

AA

Andrey Antipov in Kotlin Community
Ну это потому, что тут приходится this@... писать, чтобы получить конкретный ресивер. Сейчас получше пример сделаю
источник

P

Phoenix in Kotlin Community
Andrey Antipov
Есть ещё каррирование екстеншен лямбд. Что-то типа:
fun String.foo(): Double.() -> Int.() -> String = dbl@ { { "${this@foo} ${this@dbl} $this" } }
fun main() {
   println("bar".foo().let { 2.0.it() }.let { 1.it() })
   println("baz".foo()(3.2)(2))
}
Но идея довольно крутая, лямбда из лямбды
источник

AA

Andrey Antipov in Kotlin Community
Phoenix
Но идея довольно крутая, лямбда из лямбды
Можно ещё так:
class A(val a: String)
class B(val b: String)
class C(val c: String)

fun A.abc(): B.() -> C.() -> String = { { "$a $b $c" } }

fun main() {
   println(A("a").abc().let { B("b").it() }.let { C("c").it() })
   println(C("c").(B("b").(A("a").abc())())())
   println(A("a").abc()(B("b"))(C("c")))
}
источник

AA

Andrey Antipov in Kotlin Community
А самая интересная часть в каррированном представлении, что такую функцию можно применять только к части параметров, то есть A("a").abc() - вполне корректное выражение, как и A("a").abc()(B("b"))
источник

QH

Quantum Harmonizer in Kotlin Community
А есть что-нибудь готовое для раскаррирования?)
источник

AA

Andrey Antipov in Kotlin Community
Quantum Harmonizer
А есть что-нибудь готовое для раскаррирования?)
Это тупо нагенерить подобных функций: fun <A, B, C> ((A) -> (B) -> C).uncurry(): (A, B) -> C = { a, b -> this(a)(b) }
источник

AA

Andrey Antipov in Kotlin Community
В стрелке может быть, надо глянуть
источник