flatMap 函数签名(输入 -> 输出)是否建议它进行任何展平?

Does flatMap functional signature (input -> output) proposes its doing any flattening?

flatMap签名:

 /* applies a transformation of the monad "content" by composing
  * this monad with an operation resulting in another monad instance 
  * of the same type
  */
  def flatMap(f: A => M[B]): M[B]

是否可以通过其签名(输入到输出)(名称 flat 除外)理解其扁平化结构?或者我必须阅读它的实现才能理解吗?不是好的编码实践意味着我可以通过函数的签名(即使没有函数名称也可以输入到输出)来理解它到底做了什么?如果是这样,flatMap 如何遵循这个基本的编程实践?还是违反了

有助于理解 flatMap 定义的事物的类型也是 M 并且类似于 Traversable[A] 或子类如 List[A],或另一个 Monad,例如 OptionFuture。因此,flatMap 要求 (f: A => M[B]) 的函数定义的左侧向我们暗示该函数处理 Monad 中包含的各个项目,并为每个项目生成 M[B]。然后 returns M[B] 而不是 M[M[B]] 这一事实暗示正在发生一些扁平化。

但是我不同意应该可以通过其签名确切地知道函数的作用。例如:

Trait Number {
  def plus(that: Number): Number

  def minus(that: Number): Number
}

没有函数名称和可能还有一些文档,我认为期望另一个人知道 plusminus 做什么是不合理的。

Does flatMap functional signature (input -> output) proposes its doing any flattening?

是的,确实如此。 事实上,join(或 flatten)、mapunit 构成了实现 monad 所需的最小原始函数集。 flatMap可以根据这些其他功能来实现。

//minimal set
def join[A](mma: M[M[A]]): M[A] = ???
def map[A](ma: M[A], f: A => B): M[B] = ???
def unit[A](a: A): M[A] = ???

def flatMap[A](ma: M[A], f: A => M[B]): M[B] = join(map(ma))

现在应该清楚 flatMap 扁平化 映射的 monad 的结构。

为了比较,这是另一组最小基元,其中 join/flatten 是根据 flatMap.

实现的
// minimal set
def unit[A](a: A): M[A] = ???
def flatMap[A](ma: M[A], f: A => M[B]): M[B] = ???

def map[A](ma: M[A], f: A => B): M[B] = flatMap(ma, a => unit(f(a)))
def join[A](mma: M[M[A]]): M[A] = flatMap(mma, ma => ma)