gpt4 book ai didi

Scalaz: `scalaz.syntax.applicative._` 如何发挥它的魔力

转载 作者:行者123 更新时间:2023-12-04 21:56:09 25 4
gpt4 key购买 nike

这个问题与this one有关,我试图了解如何在 Scala 中使用 reader monad。

在答案中,作者使用以下代码获取 ReaderInt[String] 的实例:

import scalaz.syntax.applicative._
val alwaysHello2: ReaderInt[String] = "hello".point[ReaderInt]

Scala 使用哪些机制来解析表达式的类型 "hello".point[ReaderInt]以便它使用正确的 point功能?

最佳答案

任何时候你想弄清楚这样的事情的一个很好的第一步是使用反射 API 来对表达式进行脱糖:

scala> import scalaz.Reader, scalaz.syntax.applicative._
import scalaz.Reader
import scalaz.syntax.applicative._

scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}

scala> type ReaderInt[A] = Reader[Int, A]
defined type alias ReaderInt

scala> showCode(reify("hello".point[ReaderInt]).tree)
res0: String = `package`.applicative.ApplicativeIdV("hello").point[$read.ReaderInt](Kleisli.kleisliIdMonadReader)

(您通常不想在实际代码中使用 scala.reflect.runtime,但它对于此类调查非常方便。)

当编译器发现您试图调用 .point[ReaderInt] 时在没有 point 的类型上方法—在本例中 String — 它开始寻找可以转换 String 的隐式转换转换为确实具有匹配的类型 point方法(这在 Scala 中称为“浓缩”)。我们可以从 showCode 的输出中看到它找到的隐式转换是一个名为 ApplicativeIdV 的方法在 applicative语法对象。

然后将此转换应用于 String ,产生类型 ApplicativeIdV[String] 的值.这种类型的 point方法如下所示:
def point[F[_] : Applicative]: F[A] = Applicative[F].point(self)

这是这样的语法糖:
def point[F[_]](implicit F: Applicative[F]): F[A] = F.point(self)

所以接下来它需要做的是找到一个 Applicative F 的实例.在您的情况下,您已明确指定 FReaderInt .它将别名解析为 Reader[Int, _] ,它本身就是 Kleisli[Id.Id, Int, _] 的别名,并开始寻找实例。

它看起来最先出现的地方之一是 Kleisli伴随对象,因为它需要包含 Kleisli 的类型的隐式值。 ,事实上 showCode告诉我们它找到的那个是 Kleisli.kleisliIdMonadReader .到那时它就完成了,我们得到了 ReaderInt[String]我们要。

关于Scalaz: `scalaz.syntax.applicative._` 如何发挥它的魔力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38622081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com