I have a use case that is causing some trouble. We...
# announcements
e
I have a use case that is causing some trouble. We have an interface:
Copy code
interface Foo<T> { 
   fun bar(t: T)
 }
And we want to be able to have the same interface but without the parameter:
Copy code
interface Foo {
    fun bar()
}
but this is not possible because we are redeclaring the interface name. A possible solution is to declare
Foo<Unit>
and pass
Unit
instead of having the second interface without parameters, but this verbose on the calling and declaration site. We have an extension function
fun Foo<Unit>.bar() = bar(Unit)
to make the calling site clearer, but declaring it is still a little bit cumbersome. Any ideas on how to achieve this?
m
Extracting parameter from interface would work.
Copy code
interface Foo {
    fun <T> bar(t: T)
    fun bar()
}
w
I see as the
Function0
,
Function1
, etc.
Copy code
interface Foo0 : () -> Unit
    interface Foo1<in T> : (T) -> Unit

    class A : Foo1<Int> {
        override fun invoke(p1: Int) = TODO()
    }

    class B : Foo0 {
        override fun invoke() = TODO()
    }
k
@Melih Aksoy That's something completely different, now implementors of that interface need to be able to handle anything instead of only a single type.
d
How about a typealias?
typealias FooU = Foo<Unit>
That plus your extension function should make this quite seamless
e
@wbertan potentially the interface can have other methods so implementing function might not be a solution. Also, we end up declaring different interface names for each number of parameters.
@diesieben07 This is what we are using right now, but still doesn't feel 100% having to write that U at the end. But is the best we have managed so far
w
@Eric Martori This is kind of what Kotlin does: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/functions/Functions.kt Give this example based on your example where isn't showing other methods. Anyway you could implement two interfaces:
Copy code
interface OtherFoo {
        fun doSomethingElse()
    }
    interface Foo0: OtherFoo {
        fun doSomething()
    }
    interface Foo1<in T>: OtherFoo {
        fun doSomething(param: T)
    }

    class A : Foo1<Int> {
        override fun doSomething(param: Int) = TODO()
        override fun doSomethingElse() = TODO()
    }

    class B : Foo0 {
        override fun doSomething() = TODO()
        override fun doSomethingElse() = TODO()
    }