scala – 在Monad上实现`sequence`
发布时间:2020-12-16 18:16:16 所属栏目:安全 来源:网络整理
导读:从 Functional Programming in Scala开始实施Monad.sequence()的另一个练习,我的答案不同于官方/已知的正确答案: 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]())
从
Functional Programming in Scala开始实施Monad.sequence()的另一个练习,我的答案不同于官方/已知的正确答案:
Official: def sequence[A](lma: List[F[A]]): F[List[A]] = lma.foldRight(unit(List[A]()))((ma,mla) => map2(ma,mla)(_ :: _)) 矿: def序列[A](lma:List [F [A]]):F [List [A]] = F(lma.flatten) 其中F为选项的示例: 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)) 我的回答(或其精神)在这里合法吗? 我得到以下编译时异常,但我确定它是否与我对类型构造函数缺乏理解有关.
解决方法
当您编写Option(1)时,实际发生的是您在Option配对对象上调用apply方法.这只与Option类型间接相关 – 具体来说,如果你只有一个引用Something类型的类型变量,那么通常无法获得Something伴侣对象(这是一个值).事实上,并不能保证伴随对象甚至存在,即使它确实存在,它的apply方法也可能返回一些完全不是Something类型实例的东西.在List和Option以及case类的情况下,X.apply(…)确实返回X这一事实完全是一个惯例问题.
这里问题的另一部分是对List.flatten的调用.如果你在the docs中查看“完全签名”以展平,你会发现它有一个隐含的参数: def flatten[B](implicit asTraversable: (A) => GenTraversableOnce[B]): List[B] 这意味着如果A可以隐式转换为某种类型的GenTraversableOnce,则只能在List [A]上使用它.对于任何旧的monad来说,情况并非如此. 我鼓励你向自己证明这些事情,但是尝试用练习中的其他一些monad实现你的实现,看看事情发生了什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |