进行另一个练习以实现 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(...)
的事实确实返回 X
在 List
的情况下和 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/