Ale*_*ndr 6 design-patterns scala scalaz
在我们定义模块的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)
Run Code Online (Sandbox Code Playgroud)
代码稍有改动.但我们的想法是我们定义:
以上所述,它的动机以及客户如何使用它是显而易见的.但是scalaz对于每个这样的模块定义,还有一个相关的*Syntax类.我无法理解它的目的.请问exlain,为什么需要它以及如何在客户端代码中使用它.
在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]
}
Run Code Online (Sandbox Code Playgroud)
更新:
伙计们,似乎我不够清楚,或者对我们所有人来说,话题都更复杂.
我需要的是理解两个特征之间的区别:
trait ToFunctorOps {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
Run Code Online (Sandbox Code Playgroud)
与
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]
}
Run Code Online (Sandbox Code Playgroud)
两个特征都定义了一个创建的通用方法FunctorOps,两者都具有相同的可见性规则.第一个ToFunctorOps特征,它本身不是通用的,它只定义泛型方法[F[_],A].结果,我可以将很多这样的特征组合成一个对象并一次导入所有这些特征.我举了一个例子,说明客户可以使用这些特征:
object NewLibrary extends ToFunctorOps
...
import com.savdev.NewLibrary._
val r2 = List(1, 4) qmap (x=>x.toString)
Run Code Online (Sandbox Code Playgroud)
这种特性已经为客户提供了隐式注入方法的可能性.我们为什么需要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 }
}
Run Code Online (Sandbox Code Playgroud)
这可以实现以下工作方式:
def foo[F[_]](f: F[String])(implicit F: Functor[F]): F[Int] = {
import F.functorSyntax._
f.map(_.length)
}
Run Code Online (Sandbox Code Playgroud)
与添加语法的方式进行比较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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |