我正在尝试研究《猫》中的半群。以下是 Underscore 的“Scala with Cats”中的声明。
cats.Semigroupal
是一个类型类,允许我们组合上下文
trait Semigroupal[F[_]] {
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
参数fa
and fb
彼此独立:我们可以在将它们传递给之前以任一顺序计算它们product
。这与flatMap
,它对其参数施加了严格的顺序。
所以基本上,我们应该能够结合两个Either
上下文也是如此,但这似乎不起作用:
import cats.instances.either._
type ErrorOr[A] = Either[Vector[String], A]
Semigroupal[ErrorOr].product(Left(Vector("Error 1")), Left(Vector("Error 2")))
// res3: ErrorOr[Tuple2[Nothing, Nothing]] = Left(Vector("Error 1"))
如果半群的 USP 是急切地执行独立操作,则必须在传递给product
但我们无法得出综合结果。
我们可能期望product
应用于Either
积累错误而不是快速失败。再次,也许令人惊讶的是,我们发现product
实现与以下相同的快速失败行为flatMap
.
这是否与具有替代方法能够组合任何相同类型的上下文的原始前提相矛盾?
为了确保语义一致,Cats 的 Monad(扩展了 Semigroupal)提供了乘积的标准定义:map
and flatMap
.
为什么要实施product
按照map
and flatMap
?这里指的是什么语义?
那么为什么要费心半群呢?答案是我们可以创建有用的数据类型,其中包含 Semigroupal(和 Applicative)实例,但不包含 Monad。这使我们能够以不同的方式实现产品。
这究竟意味着什么?
不幸的是,这本书没有详细介绍这些前提!我也无法在网上找到资源。有人可以解释一下吗? TIA。