为Free monad构建编译器(Cats库)

时间:2017-05-12 10:29:32

标签: scala monads scala-cats free-monad

我试图让我的头围绕着monads和Cats。根据一些例子(例如cats),我编写了如下代码。但实际上,无法弄清楚如何让compiler做我需要的东西并进行编译。

import cats.Id
import cats.free.Free
import cats.~>

object Filtering extends App {

  sealed trait Filter[A]

  case class WhitespaceFilter(text: String) extends Filter[Seq[String]]

  case class LowerCaseFilter(strings: Seq[String]) extends Filter[Seq[String]]

  def whitespaceFilter(text: String): Free[Filter, Seq[String]] = Free.liftF(WhitespaceFilter(text))

  def lowerCaseFilter(strings: Seq[String]): Free[Filter, Seq[String]] = Free.liftF(LowerCaseFilter(strings))

  val process: (String => Free[Filter, Seq[String]]) = {
    text: String =>
      for {
        p1 <- whitespaceFilter(text)
        p2 <- lowerCaseFilter(p1)
      } yield p2
  }

  def compiler: Filter ~> Id  =
    new (Filter ~> Id) {
      def apply[A](fa: Filter[A]): Id[A] =
        fa match {
          // The code doesn't compile if uncommented...
          case WhitespaceFilter(text) => ??? // text.trim.split("""[\s]+""")
          case LowerCaseFilter(terms) => ??? // terms.map(_.toLowerCase)
        }
    }

  val result: Seq[String] = process("Some Text").foldMap(compiler)
  println(result) // should be Seq("some", "text")
}

谢谢!

1 个答案:

答案 0 :(得分:1)

在玩你引用的Cats示例代码时遇到了类似的问题。我正在运行IntelliJ IDEA并且IDE使用编译器错误标记了注释行,但实际上我可以运行代码并获得输出:

ArrayBuffer(some, text)

我认为IntelliJ的编译器对Id的定义感到困惑:

type Id[A] = A

我不确定IntelliJ是否使用它自己的编译器,或者它是否使用Scala编译器。如果后者为真,则可能有一种方法可以使IntelliJ使用处理此类型定义的更新的编译器。

祝你好运! :)