scala - 在 Scalaz 状态单子(monad)中查找 Shapeless HList 的类型类实例

标签 scala type-inference scalaz shapeless

假设我有一个状态单子(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 编译器推断出 SNothing而不是 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/

相关文章:

scala - Scala 如何忽略 Java 的已检查异常?

scala - 如果特质以 self : Actor 开头,这意味着什么

c# - C# 中是否可能进行部分泛型类型推断?

scala - 使用隐式推断未知类型

scala - 在Scala中将两个元组组合成一个新的更大的元组的干净方法?

scala - 对理解 Scalaz Future 和 Task 有一点帮助

scala - 解释 scalaz-7 中的 Traverse[List] 实现

scala - 无法在带有cats库的函数中调用map方法

scala - 为什么scala不能推断偏应用中省略参数的类型?

scala - 无形 : Prepend. 未找到隐式