我正在阅读来自underscore.io的scala cats book。它说关于Monad和Functor:
虽然monad和functor是最广泛使用的测序数据类型..
我可以看到Monad用于测序数据,但Functor完全不用。有人可以在仿函数上展示有关排序计算吗?
Seq(1, 2, 3).map(_ * 2).map(_.toString).foreach(println)
这里:您对一系列数据进行了一系列操作。
每个monad实际上都是一个仿函数,因为你可以使用implement map with flatMap和unit / pure /无论你的实现是什么。因此,如果您同意monad是“排序数据类型”,那么您应该同意仿函数也是如此。
脱离背景,这种说法不太清楚。
更完整的报价版本是:
虽然monad和functor是最广泛使用的测序数据类型[...],但是半群和应用程序是最常用的。
本声明的目的不是消除“序列”的函数和一元概念之间的差异,而是将它们与Semigroupal
提供的明显非顺序操作进行对比。
Functor
和Monad
都支持(不同)种类的“测序”。
对于某些函子x
和某些类型的F[X]
,给定F
类型的值X
,我们可以“序列”纯函数
f: X => Y
g: Y => Z
像这样:
x map f map g
你可以称之为“排序”,至少是“元素”。关键是g
必须等到f
产生至少一个y
类型的Y
才能做任何有用的事情。但是,这并不意味着必须在f
第一次调用之前完成g
的所有调用,例如如果x
是一个长列表,可以并行处理每个元素 - 这就是我称之为“元素”的原因。
使用代表monadic效应的monad,“排序”的概念通常会更加严肃。例如,如果您正在使用x
类型的值M[X] = Writer[Vector[String], X]
,并且您有两个具有“写入”效果的函数
f: X => M[Y]
g: Y => M[Z]
然后你像这样对它们进行排序:
x flatMap f flatMap g
你真的希望f
完全完成,直到g
开始在Vector[String]
类型的日志中写任何东西。所以在这里,这只是“排序”,没有任何精细打印。
现在,与Semigroupal
形成鲜明对比。
假设F
是半群的,也就是说,我们总是可以从F[(A,B)]
和F[A]
形成F[B]
。给出了两个功能
f: X => F[A]
g: X => F[B]
我们可以建立一个功能
(x: X) => product(f(x), g(x))
返回类型为F[(A, B)]
的结果。请注意,现在f
和g
可以完全独立地处理x
:无论它是什么,它绝对不是排序。
同样,对于Applicative
F
和功能
f: A => X
g: B => Y
c: (X, Y) => Z
和两个独立的值a: F[A]
,b: F[B]
,你可以用a
和b
完全独立地处理f
和g
,然后将结果与c
结合成一个F[Z]
:
map2(a, b){ (a, b) => c(f(a), g(b)) }
再说一次:f
和g
对彼此的输入和输出一无所知,它们完全独立工作直到最后一步c
,所以这又不是“排序”。
我希望它能在某种程度上澄清这种区别。