假设我有一个状态单子(monad),状态是 HList
我定义了一个组合器,它采用第一个 n
元素 HList
:
import scalaz._, Scalaz._
import shapeless._, ops.hlist._, Nat._
def take[S <: HList](n: Nat)(implicit tk: Take[S, n.N]):
IndexedState[S, tk.Out, Unit] = ???
for {
_ <- init[Int :: String :: HNil]
_ <- take(_1)
x <- state("abc")
} yield x
scala 编译器在类型推断期间卡住。它并不推断
S
take
的类型参数是 Int :: String :: HNil
.因此,编译器无法找到参数 tk
的隐式值。 .[error] could not find implicit value for parameter tk: shapeless.ops.hlist.Take[S,shapeless.Nat._1.N]
[error] _ <- take(_1)
我知道我可以通过简单地公开状态或修复
S
来帮助编译器。 .但我不想!这个额外的信息似乎是多余的:def take[S <: HList](hl: S, n: Nat)(implicit tk: Take[S, n.N]):
IndexedState[S, tk.Out, Unit] = ???
for {
hl <- init[Int :: String :: HNil]
_ <- take(hl, _1) // Redundant
_ <- take[Int :: HNil](_1) // Redundant
x <- state("abc")
} yield x
为什么在第一个代码片段中,scala 编译器推断出
S
如Nothing
而不是 Int :: String :: HNil
?我想知道是否有可能在不暴露状态或提供类型信息的情况下获得这项工作?提前致谢!
最佳答案
以下编译:
for {
_ <- init[Int :: String :: HNil] flatMap { _ => take(_1) }
x <- state("abc")
} yield x
for
-您的问题的循环大致翻译为init[Int :: String :: HNil] flatMap { _ =>
take(_1) flatMap { _ =>
state("abc") map { x =>
x
}
}
}
并且 scalac 似乎不愿意推断
take(_1)
的类型参数鉴于它已经必须推断出它下面的某些类型,并且您调用 flatMap
直接上它。
关于scala - 在 Scalaz 状态单子(monad)中查找 Shapeless HList 的类型类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28679016/