在Scalaz状态monad中查找Shapeless HList的类型实例

假设我有一个状态monad,状态是一个HList并且我定义了一个组合子,它接受了这个HList的前n元素:

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编译器被卡住了。 它并不推断takeS类型参数是一个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编译器推断SNothing而不是Int :: String :: HNil ? 我想知道是否可以在不暴露状态或提供类型信息的情况下获得此作品?

提前致谢!


以下编译:

for {
  _ <- init[Int :: String :: HNil] flatMap { _  => take(_1) }
  x <- state("abc")
} yield x

for你的问题的-loop大致翻译成

init[Int :: String :: HNil] flatMap { _ =>
  take(_1) flatMap { _ =>
    state("abc") map { x =>
      x
    }
  }
}

并且scalac似乎不愿意推断take(_1)的类型参数,因为它已经必须推断它下面的某些类型,并且直接调用flatMap

链接地址: http://www.djcxy.com/p/43057.html

上一篇: Find type class instance for Shapeless HList in Scalaz state monad

下一篇: Type inference of instance functions