flatMap的集合是monad吗? [英] Is a collection with flatMap a monad?

查看:93
本文介绍了flatMap的集合是monad吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Scala具有定义的特征Iterable[A]

Scala has the trait Iterable[A] that defines

def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Iterable[B] 

肯定看起来就像单子上的bind函数,文档提示它是单子,但是有两个反对意见,一个是次要,一个是主要:

That certainly looks like the bind function on a monad, and the documentation hints that it is a monad, but there are two objections, one minor and one major:

  • 次要的:传递的函数的返回类型是此GenTraversableOnce.我认为,这只是判断单调性时可以忽略的一种便利.
  • 主要的:monad的值"是它包含的所有值的列表,但是该函数一次被赋予一个值.
  • the minor one: the return-type of the function passed in is this GenTraversableOnce. I think this is just a convenience that can be overlooked when judging monad-ness.
  • the major one: the "value" of the monad is the list of all the values it contains, but the function is given the values one at a time.

这些问题是否破坏了收藏的单调性?

Do these problems break the monad-ness of the collection?

推荐答案

主要"问题更容易回答:不,不是,因为那不是什么意思.一个monad不需要具有任何特定的值"或没有任何值",只需以特定的方式与功能组合即可.

The "major" concern is easier to answer: no, it doesn't, because that's not what it means. A monad is not required to have any particular "value" or none, only to compose with functions in particular ways.

对于未成年人",您应该关注类型.恰当地,一个monad是一个monoid(具有一些附加约束),这意味着它是具有某些操作的集合.据我所知,该集合的元素是类型为A => M[B]的事物(在scalaz中,该类型称为Kleisli); flatMap是monoid的|+|操作.

For the "minor" one, you're right to be concerned about the types. Properly, a monad is a monoid (with some additional constraints), meaning it's a set with certain operations. The elements of this set are, as far as I can tell, things of type A => M[B] (in scalaz this type is called Kleisli); flatMap is the |+| operation of the monoid.

Scala中的所有可能的 A => Iterable[B]集合相对于此操作(以及适当的身份选择)是否构成一个单面体?不,不是非常,因为有很多A => Iterable[B]可能违反单子法则.对于一个简单的示例,{a: A => throw new RuntimeException()}.一个更严重的例子是如果flatMap链中存在Set,则这可能会破坏关联性:假设我们具有:

Does the set of all possible A => Iterable[B] in Scala form a monoid with respect to this operation (and a suitable choice of identity)? No, very much not, because there are plenty of possible A => Iterable[B] that violate the monad laws. For a trivial example, {a: A => throw new RuntimeException()}. A more serious example is that e.g. if a Set is present in a flatMap chain, this can break associativity: suppose we have:

f: String => Iterable[String] = {s => List(s)}
g: String => Iterable[String] = {s => Set(s)}
h: String => Iterable[String] = {s => List("hi", "hi")}

然后

((f |+| g) |+| h).apply("hi") = List("hi") flatMap h = List("hi", "hi")

但是

(f |+| (g |+| h)).apply("hi") = List("hi") flatMap {s => Set("hi")} = List("hi")

令人不安,因为monoid的全部目的是我们可以编写f |+| g |+| h,而不用担心我们用哪种方式对其进行评估.回到monads,重点是我们应该能够写

which is upsetting, because the whole point of a monoid is that we can write f |+| g |+| h and not worry about which way we evaluate it. Going back to monads, the point is that we should be able to write

for {
  a <- f("hi")
  b <- g(a)
  c <- h(b)
} yield c

,而不必担心flatMap的组成顺序.但是对于上面的fgh,您期望上面的代码给出哪个答案? (我知道答案,但这很令人惊讶).使用真正的monad时,除了作为scala编译器的实现细节之外,其他问题都不会出现,因为两种方法的答案都是相同的.

and not worry about which order the flatMaps are composed in. But for the f, g and h from above, which answer do you expect the above code to give? (I know the answer, but it's quite surprising). With a true monad, the question wouldn't come up except as a scala compiler implementation detail, because the answer would be the same either way.

另一方面, 的特定子集是否可能A => M[B],例如在 scalazz的scalazzi安全子集下实现的所有A => List[B]集合",就该定义而言构成了monad flatMap的?是(至少对于两个scala函数何时相等的公认定义).这适用于几个子集.但是我认为说Scala Iterable 通常在flatMap下形成monad并不是完全正确的.

On the other hand, does a particular subset of possible A => M[B], e.g. "the set of all A => List[B] implemented under the scalazzi safe subset of scala", form a monad with respect to that definition of flatMap? Yes (at least for the commonly accepted definition of when two scala functions are equal). And there are several subsets for which this applies. But I think it's not entirely true to say that scala Iterables in general form a monad under flatMap.

这篇关于flatMap的集合是monad吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆