在scalaz中,当我们定义模块时,我们还定义了隐式的辅助函数。这是定义的示例以及客户端如何使用它:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def fmap[F[_], A,B](as:F[A])(f:A=>B)
(implicit ff:Functor[F]):F[B] =
ff.map(as)(f)
implicit val listFunctor = new Functor[List] {
def map[A,B](as: List[A])(f: A => B): List[B] = as map f
}
}
...
import com.savdev.NewLibrary._
val r = fmap(List(1,2))(_.toString)
final class FunctorOps[F[_], A](self: F[A])(implicit ff:Functor[F]){
def qmap[B](f:A=>B):F[B] = ff.map(self)(f)
}
trait ToFunctorOps {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
object NewLibrary extends ToFunctorOps
...
import com.savdev.NewLibrary._
val r2 = List(1, 4) qmap (x=>x.toString)
代码略有更改。但想法是我们定义:
综上所述,它的动机以及客户可以使用它的方式很明显。但是在每个这样的模块定义的
scalaz
中,也有一个相关的*Syntax
类。我不明白它的目的。您能否解释一下为什么需要它,以及如何在客户端代码中使用它。在Scalaz中,其定义为:
trait FunctorSyntax[F[_]] {
implicit def ToFunctorOps[A](v: F[A]): FunctorOps[F, A] =
new FunctorOps[F, A](v)(FunctorSyntax.this.F)
def F: Functor[F]
}
更新:
伙计们,我似乎还不够清楚,或者对我们所有人来说,话题都比较复杂。
我需要了解两个特征之间的区别:
trait ToFunctorOps {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
与
trait FunctorSyntax[F[_]] {
implicit def ToFunctorOps[A](v: F[A]): FunctorOps[F, A] =
new FunctorOps[F, A](v)(FunctorSyntax.this.F)
def F: Functor[F]
}
这两个特征都定义了创建
FunctorOps
的通用方法,它们都具有相同的可见性规则。第一个
ToFunctorOps
特性,它本身不是泛型的,它仅使用[F[_],A]
定义了泛型方法。结果,我可以将很多这样的特征组合到一个对象中,然后一次将它们全部导入。我举了一个例子,客户如何使用这些特征:object NewLibrary extends ToFunctorOps
...
import com.savdev.NewLibrary._
val r2 = List(1, 4) qmap (x=>x.toString)
这种特性已经给客户提供了隐式注入(inject)方法的可能性。为什么我们需要
FunctorSyntax
?此FunctorSyntax特性是[F[_]]
上的通用名称。扩展它时,必须在定义中提供一个类型。因为现在在特质定义中使用了F[_]
,所以一个函数具有较少的通用参数,只有[A]
。我问你们,如果您能帮忙和不理解,请给我一个代码示例,客户端如何使用此
FunctorSyntax
特性。确实这还不清楚。现在,我看到尝试解释其他主题的信息,但是没有解释原始主题的信息:
ToFunctorOps
已经提供了此功能。 伙计们,请再次显示社区
USE CASES via CODE of FunctorSyntax
。代码本身始终是最好的文档。此致
最佳答案
从在scalaz代码库中看到的内容来看,我认为FunctorSyntax
是启用语法的另一种方法。他们这样定义Functor
(简化):
trait Functor {
def map[A, B](fa: F[A])(f: A => B): F[B]
val functorSyntax = new FunctorSyntax[F] { def F = Functor.this }
}
这启用了以下工作方式:
def foo[F[_]](f: F[String])(implicit F: Functor[F]): F[Int] = {
import F.functorSyntax._
f.map(_.length)
}
比较
ToFunctorOps
如何添加语法:package scalaz.syntax { // simplified version of the scalaz codebase
object functor extends ToFunctorOps
}
import scalaz.syntax.functor._
def foo[F[_]: Functor](f: F[String]): F[Int] = f.map(_.length)
关于Scalaz,*语法类的目的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50792102/