实现FreeMonad#flatMap&地图

时间:2014-03-31 03:00:13

标签: scala

完成"外部效果和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
    }

  }

从以前的练习中,我知道如何在"具体的"上实施flatMapListMonad#flatMap。为了不给我完整的答案,请你直接/告诉我如何在免费monad上实现这些功能之一?

1 个答案:

答案 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(以及amf)。