Generics 针对具体案例F<;缺少HKT的解决办法;什么都没有>;对于F<;out X>;

Generics 针对具体案例F<;缺少HKT的解决办法;什么都没有>;对于F<;out X>;,generics,kotlin,types,higher-kinded-types,Generics,Kotlin,Types,Higher Kinded Types,在Kotlin中,有没有办法通过在下面的最小示例中保留defaultBar摘要来将Foo与Bar分开 sealed class Bar<out X> { data class Hello<X>(val who: X): Bar<X>() object Empty : Bar<Nothing>() } interface Foo { fun defaultBar(): Bar<Nothing> = Bar.Empty f

在Kotlin中,有没有办法通过在下面的最小示例中保留
defaultBar
摘要来将
Foo
Bar
分开

sealed class Bar<out X> {
  data class Hello<X>(val who: X): Bar<X>()
  object Empty : Bar<Nothing>()
}

interface Foo {
  fun defaultBar(): Bar<Nothing> = Bar.Empty
  fun <P> foo(bar: Bar<P> = defaultBar()): Bar<P> = bar
}

fun main(args: Array<String>) {
  println((object : Foo{}).foo(Bar.Hello("world")))
}
不幸的是,Kotlin不能从
Bar
p-subtyof-Bar
派生出
p-subtyof-code>

此外,我也不会写这样的东西

sealed class Bar<out X> {
  data class Hello<X>(val who: X): Bar<X>()
  object Empty : Bar<Nothing>()
}

interface Foo<B, N: B> {
  fun defaultBar(): N
  fun <P : B super N> foo(bar: Bar<P> = defaultBar()): Bar<P> = bar
}

object FooImpl : Foo<Bar<Any>, Bar<Nothing>> {
  fun defaultBar(): Bar<Nothing> = Bar.Empty
}

fun main(args: Array<String>) {
  println(FooImpl.foo(Bar.Hello("world")))
}
这可以重构为:

import language.higherKinds

sealed trait Bar[+X]
case class Hello(who: String) extends Bar[String]
case object Empty extends Bar[Nothing]

trait Foo[B[+_]] {
  val defaultB: B[Nothing]
  def foo[P](b: B[P] = defaultB): B[P] = b
}

object FooImpl extends Foo[Bar] {
  val defaultB: Bar[Nothing] = Empty
}

println(FooImpl.foo(Hello("world")))
这样
Foo
就不会在任何地方提到
Bar


(可选)为什么我希望这是可能的 对于这种特殊情况,不需要完整的HKT,因为我们只需要在单个类型上评估
条码

sealed trait Bar[+X]
case class Hello(who: String) extends Bar[String]
case object Empty extends Bar[Nothing]

trait Foo[N] {
  val defaultBar: N
  def foo[P >: N](bar: P = defaultBar): P = bar
}

object FooInstance extends Foo[Bar[Nothing]] {
  val defaultBar = Empty
}

println(FooInstance.foo(Hello("world")))
如果没有更高级的代码,Java的
super
就足够了。但是,如上所述,Kotlin在使用站点上似乎没有类似于
/
super
/的类型下限


问题:
除了将
foo
移动到
FooImpl
中,即将
foo
FooImpl
合并到一个大文件中之外,还有什么可以做的吗?

你可以通过制作
foo
扩展函数并编写
B:p
来模仿
super

sealed class Bar<out X> {
    data class Hello<out X>(val who: X) : Bar<X>()
    object Empty : Bar<Nothing>()
}

interface Foo<out B> {
    fun defaultBar(): B
}

fun <B : P, P> Foo<B>.foo(bar: P = defaultBar()): P = bar

object FooImpl : Foo<Bar<Nothing>> {
    override fun defaultBar(): Bar<Nothing> = Bar.Empty
}

fun main() {
    println(FooImpl.foo(Bar.Hello("world")))
}
密封类条{
数据类Hello(val-who:X):Bar()
对象为空:Bar()
}
接口Foo{
fun defaultBar():B
}
fun Foo.Foo(bar:P=defaultBar()):P=bar
对象FooImpl:Foo{
覆盖默认栏():Bar=Bar.Empty
}
主要内容(){
println(FooImpl.foo(Bar.Hello(“世界”))
}

如果
FooImpl
实际上是另一个接口,并且我们希望将
foo
公开给实现类,那么这也可以实现:为此,我们只需将
fun foo.foo(bar:B=defaultBar()):B=bar
移动到
foo
。非常感谢你!
sealed trait Bar[+X]
case class Hello(who: String) extends Bar[String]
case object Empty extends Bar[Nothing]

trait Foo[N] {
  val defaultBar: N
  def foo[P >: N](bar: P = defaultBar): P = bar
}

object FooInstance extends Foo[Bar[Nothing]] {
  val defaultBar = Empty
}

println(FooInstance.foo(Hello("world")))
sealed class Bar<out X> {
    data class Hello<out X>(val who: X) : Bar<X>()
    object Empty : Bar<Nothing>()
}

interface Foo<out B> {
    fun defaultBar(): B
}

fun <B : P, P> Foo<B>.foo(bar: P = defaultBar()): P = bar

object FooImpl : Foo<Bar<Nothing>> {
    override fun defaultBar(): Bar<Nothing> = Bar.Empty
}

fun main() {
    println(FooImpl.foo(Bar.Hello("world")))
}