簡體   English   中英

在Scala + Cat中將任意樹與免費Monad結合使用

[英]Using arbitrary trees with Free Monads in Scala+Cats

我正在為語法創建一個庫,該庫將有兩種不同的解釋:1)基於語法分析字符串2)生成語法定義的語言中的字符串。

該庫使用貓來創建免費的monad語法的AST。 但是,這似乎並不完美,因為免費的monad會創建我的AST的列表形式表示形式,這對語句列表非常有用,但是語法離語句列表很遠,並且更接近於任意樹結構。

我設法通過使用~運算符來表示2個語法,以實現我的樹。 AST然后是本身就是任意AST的語法列表。

我的問題是:什么是在免費monad中遞歸AST的子樹的好方法?

我當前的實現在這里:

 def parserInterpreter: GrammarA ~> ParserInterpreterState =
new (GrammarA ~> ParserInterpreterState) {
  def apply[A](fa: GrammarA[A]): ParserInterpreterState[A] =
    fa match {
      case Regx(regexp) => parseRegex(regexp)
      case Optional(b)  => parseOptional(b.foldMap(this))
      case m @ Multi(g) =>
        def x: State[String, A] =
          State.apply(state => {
            g.foldMap(this)
              .run(state)
              .map {
                case (s, ParseSuccess(_))    => x.run(s).value
                case r @ (s, ParseFailure()) => (s, ParseSuccess(s).asInstanceOf[A])
              }
              .value
          })
        x
      case Choice(a, b) =>
        State.apply(state => {
          val runA = a.foldMap(this).run(state).value
          if (runA._2.asInstanceOf[ParseResult[_]].isSuccess)
            runA
          else {
            b.foldMap(this).run(state).value
          }
        })
    }
}

特別要注意的是, Multi案例使用了不安全的遞歸(即不是尾遞歸)來遞歸地解釋子樹。 有一個更好的方法嗎?

請單擊此處獲取源代碼。

如果要構建解析器/漂亮打印機庫,則要處理的對象可能不是monad。 您可能想使用貓的InvariantMonoidal (它是免費的,免費的, FreeInvariantMonoidal )。 相關的教程中有關於編解碼器的部分 ,您可能會覺得很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM