Scalaz:`scalaz.syntax.applicative._`是如何发挥作用的
这个问题与
this one有关,我试图了解如何在Scala中使用阅读器monad.
在答案中,autor使用以下代码获取ReaderInt [String]的实例: import scalaz.syntax.applicative._ val alwaysHello2: ReaderInt[String] = "hello".point[ReaderInt] Scala使用哪种机制来解析表达式“hello”.point [ReaderInt]的类型,以便它使用正确的点函数? 解决方法
每当你试图弄清楚这样的事情时,一个好的第一步是使用反射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方法的类型上调用.point [ReaderInt]时 – 在这种情况下String-it开始查找将String转换为具有匹配点的类型的隐式转换方法(在Scala中称为“浓缩”).我们可以从showCode的输出中看到,它找到的隐式转换是在applicative语法对象中称为ApplicativeIdV的方法. 然后,它将此转换应用于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) 所以它需要做的下一件事就是为F找到一个Applicative实例.在你的情况下,你明确指出F是ReaderInt.它解析了Reader [Int,_]的别名,它本身就是Kleisli [Id.Id,Int,并开始寻找实例. 它看起来的第一个地方之一将是Kleisli伴侣对象,因为它想要一个包含Kleisli的类型的隐式值,实际上showCode告诉我们它找到的那个是Kleisli.kleisliIdMonadReader.那时它就完成了,我们得到了我们想要的ReaderInt [String]. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |