完成"外部效果和I / O" Functional Programming in Scala的一章,我正在做这个练习:
//练习1:Free是任意选择F的monad。实施地图
//和Free trait上的flatMap方法,并给出Monad实例 免费[F,_]
这里是基本代码(来源 - 书籍)
sealed trait Free[F[_], A]
case class Return[F[_], A](a: A) extends Free[F, A]
case class Suspend[F[_], A](s: F[Free[F,A]]) extends Free[F,A]
case class FlatMap[F[_],A,B](s: Free[F,A],
f: A => Free[F, B]) extends Free[F,B]
def freeMonad[F[_]]: Monad[({type f[a] = Free[F, a]})#f] = {
new Monad[({type f[x] = Free[F[_], x]})#f] {
override flatMap
}
}
从以前的练习中,我知道如何在"具体的"上实施flatMap
。 ListMonad#flatMap。为了不给我完整的答案,请你直接/告诉我如何在免费monad上实现这些功能之一?
答案 0 :(得分:2)
首先,让我们删除重复:
type Free1[F[_]] = ({type f[a] = Free[F, a]})#f
记下完整的类型:
override def flatMap[A, B](mx: Free1[A])(mf: A => Free1[B]): Free1[B] = ...
通过输入Free
的定义,用Free1
重写它:
override def flatMap[A, B](mx: Free[???, ???])(mf: ???): ??? = ...
我们唯一能做的就是mx
上的模式匹配:
override def flatMap[A, B](mx: Free[???, ???])(mf: ???): ??? = mx match {
case Return(a) => ... // what can we do with a and mf to get the correct type?
case ...
}
如果你在上面的定义中输入正确的类型,右边应该相对容易填写(如果你不这样做,编译器很可能会说flatMap overrides nothing
)。如果需要,我可以扩大答案,但更喜欢错误地“不给出完整答案”方面:)
问题的答案:
不确定如何从暂停中提取免费[F,A](s:F [免费[F,A]])
你不能,因为你对F
一无所知。有没有办法没有它?
是吗?我们调用flatMap(Return(a))(mf)似乎符合flatMap的签名
a: Free[F, A]
依旧Return(a): Free[F, Free[F, A]]
,因此flatMap(Return(a))
需要Free[F, A] => Free[F, B]
而mf: A => Free[F, B]
不合适。您还应在结果中包含f
(以及a
和mf
)。