在Scala Cats中使用带有Free Monads的任意树
发布时间:2020-12-16 08:51:21 所属栏目:安全 来源:网络整理
导读:我正在为语法创建一个库,它有两种不同的解释:1)根据语法解析字符串2)用语法定义的语言生成字符串. 该库使用cat来创建语法的AST作为免费monad.然而,似乎它可能不是完美的契合,因为自由monad创建了我的AST的列表式表示,这对于语句列表很好,但是语法远离语句列
我正在为语法创建一个库,它有两种不同的解释:1)根据语法解析字符串2)用语法定义的语言生成字符串.
该库使用cat来创建语法的AST作为免费monad.然而,似乎它可能不是完美的契合,因为自由monad创建了我的AST的列表式表示,这对于语句列表很好,但是语法远离语句列表并且更接近任意树结构. 我设法通过使用?运算符来表示连接的2个语法来实现我的树.然后,AST是一个语法列表,它们本身就是任意的AST. 我的问题是:在免费monad中递归AST的子树有什么好方法? 我目前执行is here: 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 case使用不安全的递归(即不是尾递归)以便递归地解释子树.有一个更好的方法吗? Please click here for the source code. 解决方法
如果要构建Parser / Pretty打印机库,则正在操作的对象可能不是monad.你可能想要使用猫的InvariantMonoidal(和它的免费conterpart,FreeInvariantMonoidal).关于编解码器的相关教程有
a section,您可能会感兴趣.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读