Cats中具有多个参数的函数排序



我正在经历"Scala with Cats;Underscore,偶然发现了以下声明:

Cats提供了一个cats.syntax.apply模块,该模块利用SemigroupalFunctor允许用户对具有多个参数的函数进行排序。

据我所知,我们只能对具有单个参数的函数进行排序,因为函数只能返回单个值。

import cats.implicits._
val f1: Int => Int = x => x + 1
val f2: Int => Int = x => x * 4
val f3: Int => String = x => s"x = $x"
f1.map(f2).map(f3)(5)

对于以下示例,它说:内部mapN使用SemigroupalOption中提取值,并使用Functor将值应用于函数。

final case class Cat(name: String, born: Int, color: String)
(
Option("Garfield"),
Option(1978),
Option("Orange & black")
).mapN(Cat.apply)
// res10: Option[Cat] = Some(Cat("Garfield", 1978, "Orange & black"))

这里Cat.apply实际上是一个具有多个参数的函数,但它被链接到一个函数,该函数本身返回一个选项元组,即一个值。我们可能会让它接受这样的多个论点:

final case class Cat(name: String, born: Int, color: String)
val f: (String, Int, String) => (Option[String], Option[Int], Option[String]) =
(name, year, color) => (Option(name), Option(year), Option(color))
f("Garfield", 1978, "Orange & black").mapN(Cat.apply)

现在我们有了接受多个参数并链接在一起的函数fCat.apply。这就是上述声明所指的吗?但我似乎找不到进一步链接更多功能的方法。该语句是否适用于仅在一个级别链接多个参数函数?此外,请注意,与上面描述的单参数函数链接示例相比,函数f被热切地应用。在这里可以懒洋洋地应用函数吗?

我在Semigroupal网站上找不到太多的解释。有人能举个例子解释一下这句话吗?TIA。

但我似乎找不到进一步链接更多函数的方法。

我认为我们可以,因为我们可以继续映射上下文,例如

f("Garfield", 1978, "Orange & black")
.mapN(Cat.apply)
.map(_.name) // here is another step in the chain of operations

mapN是产品+幕后地图;我们可以像一样显示成分图

f("Garfield", 1978, "Orange & black")
.tupled
.map { case (a, b, c) => Cat.apply(a, b, c) }
.map { _.name }

其中CCD_ 13扩展方法最终调用CCD_。

当他们说

。。。允许用户对具有多个参数的函数进行排序。

我的解释不是我们只使用mapN保持链接,而是我们可以在函子的一般意义上继续在上下文上链接,如果在链中的某个点,通常是开始,我们在同一类型的多个上下文中有多个值,那么半群+函子允许我们在单个上下文中连接值并继续链接。

此外,请注意,与上面描述的单参数函数链接示例相比,函数f被热切地应用。在这里可以懒洋洋地应用函数吗?

这是Semigroupal相对于Monad的主要卖点,即能够";急切地";执行独立的操作,在上下文中连接结果值,然后继续链接。使用一元链,即使操作是独立的,也必须等待另一个操作才能继续链。

最新更新