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]
都有效。所以
构造函数应该工作。但似乎M
和EState
不同
这里。该如何实际编码?
此外,我怀疑S
和A
中的M
和EState
是不一样的类型。这是正确的还是受约束的?如果不是如何
应该设置一下吗?
注意:我在网站上搜索并发现了一些使用含义及其在转化中的使用的参考,但可能会弄清楚如何做到这一点。我想避免使用这样的(至少在我看来是这样的)一个冗长/复杂的解决方案。
TIA。
答案 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。