Noobe question. I have the following base trait (could be an abstract class):
trait EState[S, A] {
def retrn(a: A): EState[S, A]
def runState(s: S): (A, S)
}
which I will later extend so:
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)
}
The idea is then to use any instance above like this:
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))
}
However I get the following error:
[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))
^
I assumed that the M[S,A] would be valid for any subclass EState[S,A]. So
the constructor should work. But it seems like M and EState are different
here. How should this actually be coded?
Additionally, I suspect that that the S and A in the Mand the EState
are not the same types. Is this correct or are they bound? If not how
should one set this up?
Note: I have searched in the site and found some references to the use of implicits and their use in conversions but could out figure out how to do this. I would like to avoid using such (at least what seems to me to be such) a verbose/complicated solution.
TIA.
StateMonad3(m.retrn(a)),m.retrn( a )evaluates to an instance ofEState[ S, A ]. YourStateMonad3case class expects an argument of typeM[ S, A ]( which is a less generic type asM[ S, A ] <: EState[ S, A ]), so it won't expects anyEState[ S, A ]which is super class ofM[ S, A ]but onlyM[ S, A ]or anytypeSM[ S, A ]such thatSM[ S, A ] <: M[ S, A ].EState[S,A]. So I can pass it anAState[S,A]. Is their any type-magic I can use to make this work:def retrn(a: A): M[S,A] = m.retrn(a)? Or doesn't this make sense. BTW, can you make the comment an answer so I can give you credit?