Scala 序列计算函子

Scala 序列计算函子,scala,scala-cats,Scala,Scala Cats,我正在读下划线.io上的scala猫书。它对单子和函子的描述如下: 而单子和函子是应用最广泛的测序数据 类型 我可以看到Monad用于排序数据,但Functor完全没有。有人能介绍一下函子的排序计算吗 Seq(1, 2, 3).map(_ * 2).map(_.toString).foreach(println) 这里:您有一个数据序列上的操作序列 每一个monad实际上都是一个函子,因为您可以使用和unit/pure/无论您的实现如何调用它。所以,如果你同意单子是“排序数据类型”,那么你应该

我正在读下划线.io上的scala猫书。它对单子和函子的描述如下:

而单子和函子是应用最广泛的测序数据 类型

我可以看到Monad用于排序数据,但Functor完全没有。有人能介绍一下函子的排序计算吗

Seq(1, 2, 3).map(_ * 2).map(_.toString).foreach(println)
这里:您有一个数据序列上的操作序列

每一个monad实际上都是一个函子,因为您可以使用和unit/pure/无论您的实现如何调用它。所以,如果你同意单子是“排序数据类型”,那么你应该同意函子也是它们

这里:您有一个数据序列上的操作序列


每一个monad实际上都是一个函子,因为您可以使用和unit/pure/无论您的实现如何调用它。因此,如果你同意单子是“排序数据类型”,那么你也应该同意函子也是单子。

断章取义,这句话没有它可能说得那么清楚

更完整的报价是:

而单子和函子是最广泛使用的排序数据类型 […],半群和应用程序是最通用的

这句话的目的不是要消除“排序”的函数和一元概念之间的差异,而是要将它们与
半群
提供的明显的非顺序操作进行对比

Functor
Monad
都支持(不同)类型的“排序”

给定一个
F[x]
类型的
x
值,对于某些函子
F
和某些类型的
x
,我们可以对纯函数进行“排序”

f: X => Y
g:      Y => Z
f: X => F[A]
g: X => F[B]
f: A => X
g: B => Y
c:      (X, Y) => Z
像这样:

x map f map g
x flatMap f flatMap g
你可以称之为“排序”,至少是“元素排序”。关键是
g
必须等到
f
至少生成一个
y
类型的
y
才能执行任何有用的操作。但是,这并不意味着在第一次调用
g
之前必须完成
f
的所有调用,例如,如果
x
是一个长列表,则可以并行处理每个元素-这就是我称之为“elementwise”的原因

对于表示一元效应的单子,“排序”的概念通常更为严肃。例如,如果您正在使用类型为
M[x]=Writer[Vector[String],x]
的值
x
,并且您有两个具有“写入”效果的函数

然后按如下顺序排列它们:

x map f map g
x flatMap f flatMap g
您确实希望
f
完全完成,直到
g
开始将任何内容写入
向量[String]
类型的日志。所以这里,这只是字面上的“排序”,没有任何细节

现在,将其与
半群
进行对比

假设
F
是半群的,也就是说,我们总是可以从
F[a]
F[B]
形成a
F[(a,B)]
。给定两个函数

f: X => Y
g:      Y => Z
f: X => F[A]
g: X => F[B]
f: A => X
g: B => Y
c:      (X, Y) => Z
我们可以建立一个函数

(x: X) => product(f(x), g(x))
返回类型为
F[(A,B)]
的结果。请注意,现在
f
g
可以完全独立地处理
x
:不管它是什么,它肯定不是排序

类似地,对于
应用程序
F
和函数

f: X => Y
g:      Y => Z
f: X => F[A]
g: X => F[B]
f: A => X
g: B => Y
c:      (X, Y) => Z
和两个独立的值
a:F[a]
b:F[b]
,您可以使用
F
g
完全独立地处理
a
b
,然后将最后的结果与
c
组合成一个
F[Z]

map2(a, b){ (a, b) => c(f(a), g(b)) }
同样:
f
g
对彼此的输入和输出一无所知,它们完全独立工作,直到最后一步
c
,所以这也不是“排序”


我希望它能在某种程度上澄清这一区别。

断章取义地说,这句话没有它所能说的那么清楚

更完整的报价是:

而单子和函子是最广泛使用的排序数据类型 […],半群和应用程序是最通用的

这句话的目的不是要消除“排序”的函数和一元概念之间的差异,而是要将它们与
半群
提供的明显的非顺序操作进行对比

Functor
Monad
都支持(不同)类型的“排序”

给定一个
F[x]
类型的
x
值,对于某些函子
F
和某些类型的
x
,我们可以对纯函数进行“排序”

f: X => Y
g:      Y => Z
f: X => F[A]
g: X => F[B]
f: A => X
g: B => Y
c:      (X, Y) => Z
像这样:

x map f map g
x flatMap f flatMap g
你可以称之为“排序”,至少是“元素排序”。关键是
g
必须等到
f
至少生成一个
y
类型的
y
才能执行任何有用的操作。但是,这并不意味着在第一次调用
g
之前必须完成
f
的所有调用,例如,如果
x
是一个长列表,则可以并行处理每个元素-这就是我称之为“elementwise”的原因

对于表示一元效应的单子,“排序”的概念通常更为严肃。例如,如果您正在使用类型为
M[x]=Writer[Vector[String],x]
的值
x
,并且您有两个具有“写入”效果的函数

然后按如下顺序排列它们:

x map f map g
x flatMap f flatMap g
您确实希望
f
完全完成,直到
g
开始将任何内容写入
向量[String]
类型的日志。所以这里,这只是字面上的“排序”,没有任何细节

现在,将其与
半群
进行对比

假设
F
是半群的,也就是说,我们总是可以从
F[a]
F[B]
形成a
F[(a,B)]
。给定两个函数

f: X => Y
g:      Y => Z
f: X => F[A]
g: X => F[B]
f: A => X
g: B => Y
c:      (X, Y) => Z
我们可以建立一个函数

(x: X) => product(f(x), g(x))
返回类型为
F[(A,B)]
的结果。请注意,现在
f