gpt4 book ai didi

Scalaz,*语法类的目的

转载 作者:行者123 更新时间:2023-12-04 16:04:46 27 4
gpt4 key购买 nike

在 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)

代码略有改动。但这个想法是我们定义:
  • 抽象及其 API(代数)
  • 定义使用隐式和自身隐式的辅助泛型函数
  • 丰富现有类型以便能够使用我们的新抽象。为此使用了隐式转换。在 scalaz 中,我们在特征
  • 中为包装器和隐式转换器定义了最终类

    综上所述,它的动机以及客户如何使用它是很清楚的。但是在 scalaz对于每个这样的模块定义,还有一个相关的 *Syntax类(class)。我无法理解它的目的。您能否解释一下,为什么需要它以及如何在客户端代码中使用它。

    在 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 trait,它本身不是泛型的,它只用 [F[_],A] 定义了泛型方法.结果,我可以将很多这样的特征组合到一个对象中,并一次导入所有这些特征。我举了一个例子,客户如何使用这些特征:
    object NewLibrary extends ToFunctorOps
    ...
    import com.savdev.NewLibrary._
    val r2 = List(1, 4) qmap (x=>x.toString)

    这个特性已经为客户提供了隐式注入(inject)方法的可能性。为什么我们需要 FunctorSyntax ?这个 FunctorSyntax 特征本身是 [F[_]] 上的泛型。 .当我扩展它时,我必须在定义中提供一个类型。因为 F[_] now 用于 trait 定义,函数的泛型参数较少,只有 [A] .

    我问你们,如果你能帮助和理解,给我一个代码示例如何 FunctorSyntax特质可以被客户端使用。确切地说,这还不清楚。

    现在我看到试图解释其他主题,但不是原来的:
  • 如何创建隐式类,而不是隐式函数。
  • 最终 *Ops 类和特征之间的区别,包括它们的可见性。在这里,我们比较了具有相同可见性的 2 个特征。
  • 解释一般方法注入(inject),它们如何提供帮助。 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/

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