scala - 在 Monad 上实现 `sequence`

标签 scala monads

进行另一个练习以实现 Monad.sequence()来自 Functional Programming in Scala ,我的答案与官方/已知正确答案不同:

def sequence[A](lma: List[F[A]]): F[List[A]]



Official :
def sequence[A](lma: List[F[A]]): F[List[A]] =
  lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))

矿:
def sequence[A](lma: List[F[A]]): F[List[A]] = F(lma.flatten)
的示例女 Option :
scala> val x: List[Option[Int]] = List( Some(1), None)
x: List[Option[Int]] = List(Some(1), None)

scala> Some(x.flatten)
res1: Some[List[Int]] = Some(List(1))

我的回答(或它的精神)在这里合法吗?

我得到以下编译时异常,但我确定这是否与我对类型构造函数缺乏了解有关。

Monad.scala:15: error: not found: value F
F(lma.flatten)

最佳答案

当你写 Option(1) ,实际发生的是您正在调用 apply Option 上的方法伴生对象。这仅与 Option 非常间接相关。类型——具体来说,一般无法获得 Something如果您只有一个引用 Something 的类型变量,则伴随对象(它是一个值)类型。事实上,不能保证伴生对象是否存在,即使它确实存在,它的 apply方法可能会返回完全不是 Something 的实例的东西。类型。 X.apply(...) 的事实确实返回 XList 的情况下和 Option案例类完全是约定俗成的问题。

这里问题的另一部分是对 List.flatten 的调用。 .如果您查看 flatten 的“完整签名”在 the docs ,你会看到它有一个隐含的参数:

def flatten[B](implicit asTraversable: (A) => GenTraversableOnce[B]): List[B]

这意味着您只能在 List[A] 上使用它。如果 A可以隐式转换为 GenTraversableOnce某种。对于任何旧的 monad,一般情况下都不是这种情况。

不过,我鼓励你向自己证明这些东西——尝试使用练习中的其他一些 monad 来实现你的实现,看看哪里出了问题。

关于scala - 在 Monad 上实现 `sequence`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20037204/

相关文章:

swing - 用于 yield 设置值的 scala

scala - 我应该升级到 Intellij 终极版吗?

scala - 实时升降机编程-有可能吗?

scala - Scala 中固有层次结构中的对象初始化序列

Haskell: monadic takeWhile?

f# - 部分延迟计算构建器

Scala 测试 Mailer.sendEmailClientSuspended

haskell - 为什么要加入。 (flip fmap) 有类型 ((A -> B) -> A) -> (A -> B) -> B?

haskell - 无法让 (->) r monad 与 SDL2 渲染一起工作

c# - C# 中的 Monadic 理解语法