正在进行另一项练习以Functional Programming in Scala实施Monad.sequence()
,我的回答与官方/已知的正确答案不同:
def序列[A](lma:列表[F [A]]):F [列表[A]]
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)
F 为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:错误:未找到:值F
F(lma.flatten)
答案 0 :(得分:5)
当您撰写Option(1)
时,实际发生的是您在apply
随播广告对象上调用Option
方法。这只与Option
类型非常间接相关 - 具体来说,如果你只有一个类型变量引用{{},那么通常无法获得Something
伴随对象(这是一个值) 1}}类型。事实上,并不能保证伴随对象存在,即使它确实存在,它的Something
方法也可能返回一些完全不是apply
类型实例的东西。在Something
和X.apply(...)
以及案例类的情况下X
确实返回List
这一事实完全是一个惯例问题。
此处问题的另一部分是对Option
的调用。如果您查看the docs中List.flatten
的“完整签名”,您会看到它有一个隐含的参数:
flatten
这意味着您只能在def flatten[B](implicit asTraversable: (A) => GenTraversableOnce[B]): List[B]
上使用它,如果List[A]
可以隐式转换为某种A
。对于任何旧的monad来说,情况并非如此。
我鼓励你向自己证明这些事情,但是尝试与练习中的其他一些monad一起实施,看看事情发生了什么。