scala - 找不到类型 scalaz.Applicative 的证据参数的隐式值

标签 scala scalaz

我正在尝试减少此代码(scalaz 7.0.x,scala 2.10.x):

type Error[+A] = \/[String, A]
type Result[+A] = OptionT[Error, A]

进入这个:
type Result[+A] = OptionT[({ type λ[+α] = String \/ α })#λ, A]

我收到错误“无法找到类型 scalaz.Applicative[Main.Result] 的证据参数的隐式值”:
val result: Result[Int] = 42.point[Result]

为什么简化的代码看起来不像 scalac 的第一个例子?

最佳答案

lambda 类型的隐式解析似乎被破坏了。显然,编译器首先对类型进行脱糖,然后在类型参数的数量上不匹配。

一个“简化”的例子:

定义一个 monad 和两个特征。 One类似于 Either . Two类似于 EitherT

trait Monad[F[_]]

trait One[A, B]
object One {
  implicit def m[A]: Monad[({ type T[x] = One[A, x] })#T] = ???
}
trait Two[F[_], A]
object Two {
  implicit def m[F[_]]: Monad[({ type T[x] = Two[F, x] })#T] = ???
}

定义类型别名和案例类以部分应用 OneString因为它是第一个参数。案例类版本可用作解决方法。
type OneX[A] = One[String, A]
case class OneY[A](value: OneX[A])
object OneY {
  implicit def m(implicit ev: Monad[OneX]): Monad[OneY] = ???
}

所有“简单”类型的隐式解析都有效。
implicitly[Monad[OneX]]
implicitly[Monad[({ type T[x] = One[String, x] })#T]]
implicitly[Monad[OneY]]

定义几个部分应用的类型别名 Two
type TwoX[A] = Two[OneX, A]
type TwoY[A] = Two[({ type T[x] = One[String, x] })#T, A]
type TwoZ[A] = Two[OneY, A]

在这里我们看到使用 lambda 类型的那个失败了。
implicitly[Monad[TwoX]]
implicitly[Monad[TwoY]] // fails
implicitly[Monad[TwoZ]]

在这里我们看到所有使用类型别名的 lambda 类型都失败了。只有实际引用具有单个参数的稳定类型的那个才会成功。
implicitly[Monad[({ type T[x] = Two[OneX, x] })#T]] // fails
implicitly[Monad[({ type T[x] = Two[OneY, x] })#T]]
implicitly[Monad[({ type T[x] = Two[({ type T[x] = One[String, x] })#T, x] })#T]] //fails

我对编译器的了解相当有限,这可能与 @TravisBrown 指向的错误有关。

关于scala - 找不到类型 scalaz.Applicative 的证据参数的隐式值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24783289/

相关文章:

xml - 如何使用内胚包装器来修复这个练习?

scala - 存在类型

mysql - 避免在 SQL 语言中对数据做出与在域中相同的断言

scala - 在 scala Spark 中将训练和测试中的数据集拆分为一行

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

scala - 为什么 Scalaz 会出现在我项目的 API 文档中?

scala - 上下文绑定(bind) [T : Manifest] -> Nothing

scala - 为什么 Scala List[Int].contains 接受 Option[Int]?

scala - 隐式Monoid [Int]等在哪里实现

scala - 在函数外部导入 scalaz monad 语法