List如何成为monad?

Jam*_*ieP 4 monads scala

我认为我对Monads和monadic操作有一个基本的把握,但仍然有点停留在理解monadic类型的神奇特征如何被添加到底层类型(希望这是有道理的).

例如,我正在阅读有关a List[T]是monad的信息.但是,如果我flatMapmap一些列表依次在一个for理解中,那么它是不是真的flatMap,map那提供了monadic魔法?

如果我创造了一个List<String>那么monadic魔法是如何添加的?或者List<T>在Scala中始终是一个monad,因为它恰好是语言已经提供内置monadic支持的那些容器之一?

bad*_*ook 9

你是完全正确的,flatMapmap提供"monadic魔术".幸运或遗憾的是(取决于你看到多少糟糕的代码)编程没有魔力.没有任何抽象可以帮助您(或其他人)最终编写完成所需事物的代码.抽象"只是"让您重复使用以前编写的代码并澄清您对问题的想法.monad然后只是一个概念,一个想法,一个抽象等.

在斯卡拉的情况下,这是非常字面上的编译器的for理解,成为一个系列的flatMap,map,withFilter,和filter语句.

monad(在Scala中)可以被认为只是一个标签,你碰巧有一个类型构造函数T[_]和两个函数1

def f0[A](x: T[A], f: X => T[A]): T[A]
def f1[A](x: A): T[A]
Run Code Online (Sandbox Code Playgroud)

按照惯例,当他们看到这种现象时,Scala社区调用f0 flatMap并通常使其成为一个方法,以便x始终是父类而不是单独的参数.还有一个公约要求f1 pointpure(见scalazcats).f1通常也是一种方法,因此它不会显式地采用参数,只使用其父类作为x.

每当有人说"这样的"是一个monad时,总会有一个隐含的f0,f1并且说话者希望听众推断.严格来说," List是一个单子"是一种轻度滥用的术语.它List与函数(xs: List[A], f: A => List[A]) => xs.map(f).flatten(形式f0)和(x: A) => List(x)(形式f1)形成一个monad是一样的简写.或者稍微不那么迟钝,List以及flatMap列表上的标准和List.apply构造函数形成monad.

因此,从来没有任何魔法.作为分类某事的一部分,Monad你必须提供一个flatMap和的概念pure.

有很多方法可以将monad的抽象转换为代码.天真的方式(即没有第三方库的Scala)只是同意一个通用名称f0f1(例如flatMap)并且只是命名具有相应类型签名的方法.这基本上是scalac期望你做的for理解.你可以更进一步,尝试用a trait或a来形式化abstract class.也许称之为Monad可爱,并具有以下内容:

trait Monad[A] {
  def flatMap(f: A => Monad[A]): Monad[A]

  def pure(x: A): Monad[A]
}
Run Code Online (Sandbox Code Playgroud)

然后你可以调用任何扩展这个Monadmonad想法的实现的东西(你可以想象一些诸如此类的东西class List[A] extends Monad[A]).

出于各种实际原因,这种结果并不令人满意,因此您最终得到了通常的解决方案(看起来像是手上挥舞着许多其他复杂性)

trait Monad[F[_]] {
  def flatMap[A](f: A => F[A]): F[A]

  def pure[A](x: A): F[A]
}
Run Code Online (Sandbox Code Playgroud)

implicits 实现.


脚注:

  1. 以及一些管理其互动的法律/惯例.存在这些法律的实际原因是为程序员的生活提供理智,这样他们就知道当有人告诉他们这些功能是"一元的"时会发生什么.这些定律恰恰是对诸如monad这样的结构的推理如此有用的原因,但我不会在这里深入研究它们,因为它们在其他地方得到了充分的解释.


And*_*ann 8

Monad是一个概念而不是阶级或特征.因此,为了List[T]满足monad https://en.wikipedia.org/wiki/Monad_(functional_programming)的所有要求,可以调用它monadic.很明显,它是一个单子,因为它具有monad所提供的所有功能和能力,所以它是一个monad.

如果你想要更多的保证并且更明确地表达成为monad,你可以使用Scalaz.此链接显示了如何并提供了monad法律的详细信息:http://eed3si9n.com/learning-scalaz/Monad+laws.html