overview
I'm trying to infer types of cats.data.IndexedStateT[F[_], SA, SB, A]
passed in to the flatMap method. When just using flatMap, type inference seem to infer the type parameters for SA, SB and A correctly. However, when I use map within the flatMap it fails.
Is there a way to make this type inference work without manually specifying the type parameters for IndexedStateT passed into flatMap?
class X
class Y
// Type inference works well when just using flatMap
val res1: IndexedStateT[Eval, Unit, Y, Y] =
IndexedStateT[Eval, Unit, X, X](_ => Eval.now(new X, new X))
.flatMap { x =>
IndexedStateT(_ => Eval.now(new Y, new Y)) // Infers IndexedStateT[Eval, X, Y, Y]
}
// Type inference fails when mapping inside flatMap
val res2: IndexedStateT[Eval, Unit, Y, (X, Y)] =
IndexedStateT[Eval, Unit, X, X](_ => Eval.now(new X, new X))
.flatMap { x =>
IndexedStateT(_ => Eval.now(new Y, new Y)).map(x -> _) // Fails to infer the types for IndexedStateT[Eval, X, Y, Y] "missing parameter type"
}
Usage context
I'm using a specialised type of State monad in application code
type HListState[SA <: HList, A] = IndexedStateT[Eval, SA, A :: SA, A]
object HListState {
def apply[SA <: HList, A](fn: SA => A): HListState[SA, A] = IndexedStateT[Eval, SA, A :: SA, A](sa => Eval.now((fn(sa) :: sa, fn(sa))))
}
// Type inference works here
val res3: IndexedStateT[Eval, HNil, Y :: X :: HNil, Y] =
HListState[HNil, X](_ => new X).flatMap { x =>
HListState(_ => new Y)
}
// Inference not so good :(
val res4: IndexedStateT[Eval, HNil, Y :: X :: HNil, (X, Y)] =
HListState[HNil, X](_ => new X).flatMap { x =>
HListState(_ => new Y).map(x -> _) // <--- type inference fails here :( "missing parameter type"
}
Is there a way to get the type inference working in this case?