我想更新以前的答案,但由于您创建了单独的问题,所以我把它放在这里。
scalaz.syntax
让我们考虑point 示例,您可以将相同的推理应用于其他方法。
point(或haskell 的return)或pure(只是一个类型别名)属于Applicative 特征。如果你想在F 中添加一些东西,你至少需要Applicative 实例来处理这个F。
通常,您将通过导入隐式提供它,但您也可以显式指定它。
在第一个问题的示例中,我将其分配给val
implicit val KA = scalaz.Kleisli.kleisliIdApplicative[Int]
因为 scala 无法为这个应用程序找出对应的 Int 类型。换句话说,它不知道 Applicative for 要引入哪个 Reader。(尽管有时编译器可以弄清楚)
对于只有一个类型参数的 Applicatives,我们可以通过 import 引入隐式实例
import scalaz.std.option.optionInstance
import scalaz.std.list.listInstance
等等……
好的,你有实例。现在你需要在它上面调用point。
你有几个选择:
1.直接访问方式:
scalaz.std.option.optionInstance.point("hello")
KA.pure("hello")
2。从隐式上下文中显式拉取它:
Applicative[Option].point("hello")
如果你查看 Applicative 对象,你会看到
object Applicative {
@inline def apply[F[_]](implicit F: Applicative[F]): Applicative[F] = F
}
apply 的实现,仅返回某些类型 F 对应的 Applicative[F] 实例。
所以Applicative[Option].point("hello") 被转换为
Applicative[Option].apply(scalaz.std.option.optionInstance)
最后就是optionInstance
3.使用语法
import scalaz.syntax.applicative._
将此方法带入隐式作用域:
implicit def ApplicativeIdV[A](v: => A) = new ApplicativeIdV[A] {
val nv = Need(v)
def self = nv.value
}
trait ApplicativeIdV[A] extends Ops[A] {
def point[F[_] : Applicative]: F[A] = Applicative[F].point(self)
def pure[F[_] : Applicative]: F[A] = Applicative[F].point(self)
def η[F[_] : Applicative]: F[A] = Applicative[F].point(self)
} ////
那么,每当您尝试在 String 上调用 point 时
"hello".point[Option]
编译器意识到String 没有point 方法并开始查看隐含,它如何从String 获取具有point 的东西。
发现,可以将String转换成ApplicativeIdV[String],确实有point的方法:
def point[F[_] : Applicative]: F[A] = Applicative[F].point(self)
所以最后 - 你的电话取消了
new ApplicativeIdV[Option]("hello")
scalaz 中的所有类型类或多或少都以相同的方式工作。
对于sequence,实现是
def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] =
traverse(fga)(ga => ga)
G 后面的冒号表示应该隐式提供Applicative[G]。
本质上是一样的:
def sequence[G[_], A](fga: F[G[A]])(implicit ev: Applicative[G[_]]): G[F[A]] =
traverse(fga)(ga => ga)
所以你只需要 Applicative[G] 和 Traverse[F]。
import scalaz.std.list.listInstance
import scalaz.std.option.optionInstance
Traverse[List].sequence[Option, String](Option("hello"))