Scala类型类参数:绑定和子类化 - 类型不匹配

时间:2015-03-16 09:14:19

标签: scala class parameters subclass type-mismatch

Noobe问题。我有以下基本特征(可能是一个抽象类):

trait EState[S, A] {
  def retrn(a: A): EState[S, A]
  def runState(s: S): (A, S)
}

我稍后会这样做:

case class AState[S, A](val f: S => (A, S)) extends EState[S,A] {
  override def retrn(a: A): AState[S, A] = AState({ s: S => (a, s) })
  override def runState(s: S) = f(s)
}

然后想法使用上面的任何实例:

case class StateMonad3[S, A, M[S,A] <: EState[S, A]](m : M[S,A]) {
  def retrn(a: A): EState[S, A] = m.retrn(a)
  def retrni(a: A): StateMonad3[S, A, M] = StateMonad3(m.retrn(a))
}

但是我收到以下错误:

[info] Compiling 1 Scala source to gnosis_server/target/scala-2.10/classes...
[error] gnosis_server/examples/lang/scala/StateMonad.scala:138: type mismatch;
[error]  found   : lang.scala.EState[S,A]
[error]  required: M[S,A]
[error]   def retrni(a: A): StateMonad3[S, A, M] = StateMonad3(m.retrn(a))
                                                                      ^

我假设M[S,A]对任何子类EState[S,A]都有效。所以 构造函数应该工作。但似乎MEState不同 这里。该如何实际编码?

此外,我怀疑SA中的MEState 是不一样的类型。这是正确的还是受约束的?如果不是如何 应该设置一下吗?

注意:我在网站上搜索并发现了一些使用含义及其在转化中的使用的参考,但可能会弄清楚如何做到这一点。我想避免使用这样的(至少在我看来是这样的)一个冗长/复杂的解决方案。

TIA。

1 个答案:

答案 0 :(得分:1)

如果你看一下StateMonad3(m.retrn(a))篇,m.retrn(a)会返回EState[S, A],但StateMonad3会应用函数需要M[S, A] EState[S, A]子类。完全使用相同的推理,您无法将AnyVal传递给接受Int的函数。

另一项改进,您在val定义中使用的AState关键字是多余的。 case类apply函数参数默认为val,并将定义为case class fields。