用于序列计算的函子

Functor for sequence computation

我正在阅读 underscore.io 的 scala cats 书。它说了以下关于 Monad 和 Functor 的内容:

While monads and functors are the most widely used sequencing data types..

我可以看到 Monad 正在用于排序数据,但 Functor 根本没有。有人可以展示关于仿函数的排序计算吗?

Seq(1, 2, 3).map(_ * 2).map(_.toString).foreach(println)

此处:您对一系列数据进行了一系列操作。

每个 monad 实际上都是一个仿函数,因为您可以 implement map with flatMap 和 unit/pure/whatever 您的实现调用它。因此,如果您同意 monad 是 "sequencing data types",那么您应该同意仿函数也是它们。

如果断章取意,这个说法就不太清楚了。

引用的完整版本是:

While monads and functors are the most widely used sequencing data types [...], semigroupals and applicatives are the most general.

此声明的目的不是消除 "sequencing" 的函子和单子概念之间的差异,而是将它们与 Semigroupal 提供的明显 non-sequential 操作进行对比。

FunctorMonad 都支持(不同的)类型 "sequencing"。

给定一个 x 类型 F[X] 的值 F 和一些类型 X,我们可以 "sequence" pure 函数

f: X => Y
g:      Y => Z

像这样:

x map f map g

你可以叫这个"sequencing",至少"elementwise"。关键是 g 必须等到 f 产生至少一个 y 类型的 Y 才能做任何有用的事情。然而,这并不意味着 f 的所有调用必须在 g 首次调用之前完成,例如如果 x 是一个长列表,则可以并行处理每个元素 - 这就是我将其命名为 "elementwise".

的原因

对于表示单子效果的单子,通常会更认真地对待 "sequencing" 的概念。例如,如果您正在使用 M[X] = Writer[Vector[String], X] 类型的值 x,并且您有两个具有 "writing"-effect

的函数
f: X => M[Y]
g:        Y => M[Z]

然后像这样对它们进行排序:

x flatMap f flatMap g

您确实希望 f 完全完成,直到 g 开始将任何内容写入 Vector[String] 类型的日志。所以在这里,这实际上只是 "sequencing",没有任何 fine-print.

现在,将其与 Semigroupal 进行对比。

假设F是半群的,即我们总是可以从F[A]F[B]组成一个F[(A,B)]。给定两个函数

f: X => F[A]
g: X => F[B]

我们可以构建一个函数

(x: X) => product(f(x), g(x))

returns 结果类型 F[(A, B)]。请注意,现在 fg 可以完全独立地处理 x:不管它是什么,它肯定是 不排序

类似地,对于 Applicative F 和函数

f: A => X
g: B => Y
c:      (X, Y) => Z

和两个独立的值a: F[A]b: F[B],你可以用fg完全独立地处理ab,然后将最后的结果与 c 组合成一个 F[Z]:

map2(a, b){ (a, b) => c(f(a), g(b)) }

同样:fg 对彼此的输入和输出一无所知,他们完全独立地工作,直到最后一步 c,所以这又不是"sequencing".

我希望它能在一定程度上澄清区别。