Ich versuche Monade transfromers von scalaz
in Haskell Art und Weise zu stapeln:Stacking Monade Transformatoren in scala
statyReader :: (MonadReader Int m, MonadState Int m) => m Int
scala:
def statyReader[F[_]](implicit r: MonadReader[F, Int], s: MonadState[F, Int]): F[Int] = for {
counter <- s.get
secret <- r.ask
_ <- s.put(counter + secret)
} yield counter
Es kompiliert mit 1 implizit vergangen, aber nicht mit 2 :
Error:(13, 18) value flatMap is not a member of type parameter F[Int]
counter <- s.get
^
Error:(14, 18) value flatMap is not a member of type parameter F[Int]
secret <- r.ask
^
Error:(15, 21) value map is not a member of type parameter F[Unit]
_ <- s.put(counter + secret)
^
Warum passiert das? Meine Vermutung ist, dass Compiler jetzt verwirrt ist, die "monadische Instanz von F[_]
" sollte wählen (beide MonadReader und MonadState erweitern Monad[F[_]
). Ist das eine richtige Schätzung?
Wie überwinde ich das?
Minor Punkt: In Haskell, würde ich nicht Nennen Sie das "Stacking Monad Transformers", da ich damit zB auf 'StateT s (LeserT r IO) a '. Es ist jedoch richtig, dass wir in einem solchen Stapel mehrere Typenbeschränkungen haben, also ist es verwandt. – chi
Ich glaube nicht, dass die zwei impliziten Parameter das Problem sind, sonst würden Sie den Fehler "mehrdeutige implizite Werte" erhalten (siehe https://github.com/scalaz/scalaz/issues/1110). – devkat
@devkat wenn ich nur 1 implizit übergebe, funktioniert die Sache :) –