我正在阅读来自underscore.io的scala cats book。它说关于Monad和Functor:
虽然monad和functor是最广泛使用的测序数据 类型..
我可以看到Monad用于测序数据,但Functor完全不用。有人可以展示关于仿函数的排序计算吗?
答案 0 :(得分:3)
Seq(1, 2, 3).map(_ * 2).map(_.toString).foreach(println)
这里:您对一系列数据有一系列操作。
每个monad实际上都是一个仿函数,因为你可以implement map with flatMap和unit / pure /你的实现所谓的。因此,如果您同意monad是"对数据类型进行排序"那么您应该同意仿函数为它们。
答案 1 :(得分:2)
脱离背景,这种陈述不太清楚。
报价的更全面的版本是:
虽然monad和functor是使用最广泛的测序数据类型 [...],半群和申请人是最一般的。
本声明的目的不是消除“排序”的函数和一元概念之间的差异,而是将它们与Semigroupal
提供的明显非顺序操作进行对比。
Functor
和Monad
都支持(不同)“排序”。
对于某个仿函数x
和某些类型F[X]
,给定F
类型的值X
,我们可以“序列”纯函数< / p>
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]
,并且您有两个函数使用“writing”-effect
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
,所以这又不是“排序”
我希望它能在某种程度上澄清这种区别。