scala - mapN 过组合 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)
,以便mapN
使用组合应用Apply
?
解决方案
这正是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
上面的代码启用编译器标志才能编译。或者,您可以添加一些类型参数,但我不知道在哪里需要它们,如果你无论如何,用 Cats 做任何事情-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
.
推荐阅读
- python - ResNet50 模型在 keras 中没有通过迁移学习进行学习
- sql - 查询以以特定格式将列中的数据显示为行的方式来构造表
- javascript - 使用 react native 控制顶栏
- azure - Azure 中的专用终结点
- javascript - JS - iOS 上的 Safari - 如何获取视口比例属性
- python - 是否有任何内置函数可以将科学计数法数字转换为普通浮点数?
- string - 如何将 Talend 中所有列的空字符串转换为 null
- ruby - 带有Mailgun的Rails 6 ActionMailbox返回404
- python - 对不在列表中的列进行分组和求和
- angular - ng 将应用程序生成到特定文件夹(没有项目文件夹)