gpt4 book ai didi

scala - 为什么编译器想不通 (_ > : T) => (_ <: V[_ <: U]) <: T => V[U] for V[+_]?

转载 作者:行者123 更新时间:2023-12-01 06:05:02 30 4
gpt4 key购买 nike

所以我玩了一会儿,试图写一些关于存在和变化的东西,我遇到了这段有趣的代码。

final case class Box[+T](val value: T) {
def >>=[U](f: T => Box[U]) = f(value)
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>= f
}

这无法编译:
Variance.scala:3: no type parameters for method >>=: (f: T => Box[U])Box[U] exist so that it can be applied to arguments (_$1 => _$2)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : _$1 => _$2 where type _$2 <: Box[_ <: U], type _$1 >: T
required: T => Box[?U]
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>= f
^
Variance.scala:3: type mismatch;
found : _$1 => _$2 where type _$2 <: Box[_ <: U], type _$1 >: T
required: T => Box[U]
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>= f
^

我觉得很奇怪,因为不是 (_ >: T) => (_ <: Box[_ <: U]) T => Box[U] 的子类型?因为 Function1在第一个类型参数中是逆变的,这是 T => (_ <: Box[_ <: U]) 的子类型.自 Function1结果类型是协变的,这是 T => Box[_ <: U] 的子类型,以及自 Box它的参数是协变的,不是整个事物都是 T => Box[U] 的子类型?

奇怪的是,将代码更改为
// This change is not required ;)
type Box[T] = `What A Category Theorist Calls "The Identity Monad" And What Everyone Else Calls "A Box"`[T]
final case class `What A Category Theorist Calls "The Identity Monad" And What Everyone Else Calls "A Box"`[+T](val value: T) {
def >>=[U](f: T => Box[U]) = f(value)
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>= (f: T => Box[U])
}

带有类型归属以“提示”编译器 f: T => Box[U]使它编译。既然这里没有隐式转换或变量声明,这不应该没有区别吗?

我发现让这个编译的另一种方式是编写
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this.>>=[U](f)

这让我相信问题不大,因为编译器很难获得 (_ >: T) => (_ <: Box[_ <: U]) <: T => Box[U]以及更多它无法推断 >>= 的类型参数,这似乎是错误消息所暗示的。

(使用 Scala 2.12.1(使用 sbt,如果有任何改变))

最佳答案

final case class Box[+T](val value: T) {
def >>=[U](f: T => Box[U]) = f(value)
def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>= f
}
flatMap回传类型是 Box[U] , 但要使用 this >>= f .

所以 >>=会自动改成 f类型 (_ >: T) => (_ <: Box[_ <: U]) .

所以 Box[(_ >: T) => (_ <: Box[_ <: U])]不匹配 Box[U] .

我认为你可以这样改变: def flatMap[U](f: (_ >: T) => (_ <: Box[_ <: U])): Box[U] = this >>=[U] f

关于scala - 为什么编译器想不通 (_ > : T) => (_ <: V[_ <: U]) <: T => V[U] for V[+_]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41213696/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com