i'm trying stack monad transfromers of scalaz
in haskell way:
statyreader :: (monadreader int m, monadstate int m) => m int
scala:
def statyreader[f[_]](implicit r: monadreader[f, int], s: monadstate[f, int]): f[int] = { counter <- s.get secret <- r.ask _ <- s.put(counter + secret) } yield counter
it compiles 1 implicit passed, not 2:
error:(13, 18) value flatmap not member of type parameter f[int] counter <- s.get ^ error:(14, 18) value flatmap not member of type parameter f[int] secret <- r.ask ^ error:(15, 21) value map not member of type parameter f[unit] _ <- s.put(counter + secret) ^
why happening? guess compiler confused "monadic instance of f[_]
" should pick(both monadreader , monadstate extend monad[f[_]
). right guess?
how overcome this?
this not answer, maybe helps bit.
i think you're right; seems compiler can't unify f[_]
types of both parameters (i guess since higher-kinded type multiple possible instances , not concrete type instance) monad type. compilation works separate parameter lists since type unification happens within parameter list. can further illustrated this:
def statyreader[f[_]](implicit r: monadreader[f, int], s: monadstate[f, int]): f[int] = statyreader2(r, s) def statyreader2[f[_]:monad](r: monadreader[f, int], s: monadstate[f, int]): f[int] = { counter <- s.get secret <- r.ask _ <- s.put(counter + secret) } yield counter error: ambiguous implicit values: both value s of type scalaz.monadstate[f,int] , value r of type scalaz.monadreader[f,int] match expected type scalaz.monad[f]
obviously, workaround use 2 parameter lists choose monad want use:
def statyreader[f[_]](implicit r: monadreader[f, int], s: monadstate[f, int]): f[int] = statyreader2(r)(s) def statyreader2[f[_]](r: monadreader[f, int])(implicit s: monadstate[f, int]): f[int] = { counter <- s.get secret <- r.ask _ <- s.put(counter + secret) } yield counter
Comments
Post a Comment