scala - 在状态单子中使用 flatMap 映射时类型推断失败
问题描述
概述
我试图推断cats.data.IndexedStateT[F[_], SA, SB, A]
传入 flatMap 方法的类型。仅使用 flatMap 时,类型推断似乎可以正确推断 SA、SB 和 A 的类型参数。但是,当我在 flatMap 中使用 map 时,它会失败。
有没有办法在不手动指定传递给 flatMap 的 IndexedStateT 的类型参数的情况下使这种类型推断工作?
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"
}
使用上下文
我在应用程序代码中使用了一种特殊类型的 State monad
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"
}
有没有办法让类型推断在这种情况下工作?
解决方案
如果没有map
,编译器可以使用预期的类型res1
来计算 的类型参数flatMap
等等IndexedStateT
。但是,当您添加 时map
,呼叫没有预期的类型IndexedStateT
。
如果不进行测试,我无法确定,但我希望指定参数类型 ( SA
) 就足够了,其余的应该可以毫无问题地推断出来:
IndexedStateT { _: X => Eval.now(new Y, new Y) }.map(x -> _)
推荐阅读
- go - 如何在 Cobra 的子命令上调用 SetOut()?
- azure - 在我是所有者的地方查找 Azure 订阅
- javascript - 用两个键对 Json 数据进行分组并获取总数
- angular - 依赖于另一个预加载远程模块的角加载远程模块
- excel - Excel 密码
- docker - VPN 服务器无法从外部访问自身
- react-hooks - React Hooks - 生成函数中的 onClick
- c - 从数组类型转换为结构
- assembly - 使用 STM32F446RE 将二进制数转换为 ASCII 码
- firebase - 无法使用 nodemailer-express-handlebars 将来自另一个集合的数据绑定到 Firestore 触发函数中的 HBS)