mapN 过度组合 Apply
mapN over composed Apply
我知道我可以编写 Apply
来处理嵌套结构,例如
def mapAll[A, B, C, D](o1: List[Option[A]],
o2: List[Option[B]],
o3: List[Option[C]])
(f: (A, B, C) => D)
: List[Option[D]] = {
import cats._
import cats.implicits._
Apply[List].compose[Option].map3(o1, o2, o3)(f)
}
但是,有没有办法说服编译器接受 (o1, o2, o3).mapN(f)
而不是 Apply[List].compose[Option].map3(o1, o2, o3)(f)
,以便使用组合的 Apply
应用 mapN
?
这正是 cats.data.Nested
的用途:
def mapAll[A, B, C, D](o1: List[Option[A]],
o2: List[Option[B]],
o3: List[Option[C]])
(f: (A, B, C) => D)
: List[Option[D]] = {
import cats.data.Nested
import cats.instances.list._, cats.instances.option._
import cats.syntax.apply._
(Nested(o1), Nested(o2), Nested(o3)).mapN(f).value
}
(请注意,您需要为上面的代码启用 -Ypartial-unification
编译器标志才能编译。或者,您可以添加一些类型参数,但我不知道具体在哪里他们是必需的,如果你要用猫做任何事情,无论如何 -Ypartial-unification
是非常必要的。)
您也可以只使组合实例隐式可用:
import cats.Apply
import cats.instances.list._, cats.instances.option._
import cats.syntax.apply._
type ListOption[x] = List[Option[x]]
implicit val listOptionApply: Apply[ListOption] = Apply[List].compose[Option]
def mapAll[A, B, C, D](o1: ListOption[A],
o2: ListOption[B],
o3: ListOption[C])
(f: (A, B, C) => D)
: List[Option[D]] = (o1, o2, o3).mapN(f)
虽然这确实不理想——它是非标准的并且极其脆弱(例如,类型别名是指导解析所必需的)。
在我看来,你最好的选择就是明确地写出 Apply[List].compose[Option]
并跳过花哨的元组语法,但如果你真的必须拥有花哨的元组语法,请使用 Nested
。
我知道我可以编写 Apply
来处理嵌套结构,例如
def mapAll[A, B, C, D](o1: List[Option[A]],
o2: List[Option[B]],
o3: List[Option[C]])
(f: (A, B, C) => D)
: List[Option[D]] = {
import cats._
import cats.implicits._
Apply[List].compose[Option].map3(o1, o2, o3)(f)
}
但是,有没有办法说服编译器接受 (o1, o2, o3).mapN(f)
而不是 Apply[List].compose[Option].map3(o1, o2, o3)(f)
,以便使用组合的 Apply
应用 mapN
?
这正是 cats.data.Nested
的用途:
def mapAll[A, B, C, D](o1: List[Option[A]],
o2: List[Option[B]],
o3: List[Option[C]])
(f: (A, B, C) => D)
: List[Option[D]] = {
import cats.data.Nested
import cats.instances.list._, cats.instances.option._
import cats.syntax.apply._
(Nested(o1), Nested(o2), Nested(o3)).mapN(f).value
}
(请注意,您需要为上面的代码启用 -Ypartial-unification
编译器标志才能编译。或者,您可以添加一些类型参数,但我不知道具体在哪里他们是必需的,如果你要用猫做任何事情,无论如何 -Ypartial-unification
是非常必要的。)
您也可以只使组合实例隐式可用:
import cats.Apply
import cats.instances.list._, cats.instances.option._
import cats.syntax.apply._
type ListOption[x] = List[Option[x]]
implicit val listOptionApply: Apply[ListOption] = Apply[List].compose[Option]
def mapAll[A, B, C, D](o1: ListOption[A],
o2: ListOption[B],
o3: ListOption[C])
(f: (A, B, C) => D)
: List[Option[D]] = (o1, o2, o3).mapN(f)
虽然这确实不理想——它是非标准的并且极其脆弱(例如,类型别名是指导解析所必需的)。
在我看来,你最好的选择就是明确地写出 Apply[List].compose[Option]
并跳过花哨的元组语法,但如果你真的必须拥有花哨的元组语法,请使用 Nested
。