【问题标题】:Option is both a functor and a monad?选项既是函子又是单子?
【发布时间】:2019-05-29 21:24:49
【问题描述】:

Scala 的Option 既是单子又是函子?

据我了解,functor 只是一种公开以下 API 的数据类型:

函子

  • wrap(或apply)接受一个原语并将其包装在函子内

  • map 接受函子,解包,应用某些函数并重新包装

所以Option 是一个函子。因为我可以将Option 应用于给我Option[T] 的原语。我也可以在Optionmap 获取函子内部的内容并在Option 中重新打包。

monad 有何不同?我原以为 monad 也有 apply 函数和 map 函数。从this article 我推测一个单子flatMap?哪个被简单地定义为 map 但没有在 monad 中重新打包结果? (或者是 map 没有将结果重新打包到函子中?!)

既然Option 同时提供mapflatMap,这是否意味着Option 既是函子又是monad?

【问题讨论】:

  • 每个 Monad 也是一个 Functor。不仅是Option,还有任何Monad。 - 其次,apply 不是来自 Functor,而是来自 Applicative (这也意味着每个 Applicative 也是一个 Functor,每个Monad也是一个Aplicative)。 - 第三,是的,一个 Monad 被定义为还有一个 flatMap,它最好被认为是一个知道内部上下文的 map,或者是一个 map,后跟一个 flatten。但是,恕我直言,区分它们的最佳方法是类型,map[A, B](fa: F[A])(f: A => B): F[B] VS flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
  • 您可能会发现 infographic (by tpolecat) 对了解分类类型类之间的关系很有用。
  • Option 本身不是函子或单子。函子是一个三元组(满足函子定律);某些类型 (F)、单位函数 ((A) => F[A]) 和映射函数 ((F[A], A => B) => F[B])。 monad 是一个三元组(满足 monad 法则);某种类型 (M)、单位函数 ((A) => M[A]) 和 flatMap(或绑定)函数 ((M[A], A => M[B]) => M[B])。
  • @franklin 不是真的,让我用上下文扩展我的意思。大多数“monads” (引号是为了讨论它们实际上不是monads),例如OptionEitherListIO被称为 ContextsEffects,这是因为它们封装了 pure 值,这些值具有额外的 side-effect 关联与它们(此过程称为reification,例如Option 封装了非总计算的效果,或者换句话说,一个可能或可能的值不存在。希望这可以清楚上下文是什么,让我们回顾一下我为什么要使用 “aware”
  • @franklin 是的,我只需将 “我可能会收到一个也包含在上下文中的输入” 更改为 我会 (它是不是可选的) 接收也包装在上下文中的输入 - “所以我将解开输入执行一些功能并将输出包装在上下文中”是的,您会将结果包装在上下文中,但函数的结果也包装在上下文中,因此,您也需要将其解包。但是,是的,mapflatMap 都会传播上下文。恕我直言,理解它们的一个很好的练习是从头开始为OptionListIO等各种类型实现它们。

标签: scala monads functor


【解决方案1】:

简短回答:是的。

更长的答案:每个单子都是一个应用函子,每个应用函子都是一个函子。在面向对象的术语中:Monad <: applicative functor.>

【讨论】:

    猜你喜欢
    • 2018-07-31
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2016-09-27
    相关资源
    最近更新 更多