用于序列计算的Functor

时间:2018-03-01 08:52:29

标签: scala scala-cats

我正在阅读来自underscore.io的scala cats book。它说关于Monad和Functor:

  

虽然monad和functor是最广泛使用的测序数据   类型..

我可以看到Monad用于测序数据,但Functor完全不用。有人可以展示关于仿函数的排序计算吗?

2 个答案:

答案 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提供的明显非顺序操作进行对比。

FunctorMonad都支持(不同)“排序”。

对于某个仿函数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)]的结果。请注意,现在fg可以完全独立地处理x:不管它是什么,它肯定是没有排序

同样,对于Applicative F和函数

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

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

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

再次:fg对彼此的输入和输出一无所知,它们完全独立工作直到最后一步c,所以这又不是“排序”

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