【问题标题】:How to implement flatMap for Option如何为 Option 实现 flatMap
【发布时间】:2014-11-03 09:38:23
【问题描述】:

我正在尝试将mapflatMap 实现为Option 的扩展/丰富,而不是作弊并查看它是如何在Scalaz 中实现的。

所以这是我在卡住之前得到的结果:

package extensions.monad

trait Monad[M[_]] {
  // >>= :: Monad m => m a -> (a -> m b) -> m b
  def flatMap[A, B](input: A => M[B]): M[B]
}

trait Functor[F[_]] {
  // fmap :: Functor f => (a -> b) -> f a -> f b
  def map[A, B](input: A => B): F[B]
}

object MOption {
  implicit class MonadicOption[A](left: Option[A]) extends Monad[Option[A]] with Functor[Option[A]] {
    def flatMap[A, B](right: A => Option[B]): Option[B] = ???

    def map[A, B](right: A => B): Option[B] = ???
  }
}

我真正需要的只是基本功能,所以我可以这样做:

Some(3).flatMap(x => Some(4).map(y => x + y))

有什么提示吗?

【问题讨论】:

  • 我将从正确定义 Monad 开始。 const(或 return 或者你想怎么称呼它)在哪里?
  • @sschaef 我只使用了最基本的功能,即 monad 的 bind(这里是 flatMap)函数,当我开始使用 return 时会打扰它跨度>
  • 您不想通过查看 scalaz 来作弊,但您要求解决 SO?我不明白。
  • @GabrielePetronella 我有我的理由,也许 SO 有一个更好/更简单的解决方案,因为我不希望在 scalaz 的实现中找到完整的功能
  • monad最基本的功能是bindconst。当其中一个缺失时,您无法实现 monad。

标签: scala monads scala-option enrich-my-library flatmap


【解决方案1】:
def flatMap[A, B](right: A => Option[B]): Option[B] = left match {
  None => None
  Some(x) => right(x)
}

或类似于 scala std 库的功能

def flatMap[A, B](right: A => Option[B]): Option[B] =
  if (left.isEmtpy) None else right(left.get)

【讨论】:

  • 当我尝试匹配 right 而不是 left 时,我感觉自己做错了什么
  • @ElectricCoffee,顺便说一句,您可以从方法中删除 A 参数,因为它已经在类中。
  • 是的,我已经这样做了,尽管如果我从函数中删除它,我必须将它添加到特征中,除非你也有更聪明的方法来解决这个问题
  • @ElectricCoffee 不,恐怕在这种情况下你必须把它留在方法上。
猜你喜欢
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多