scala – 将Monad包装成解析器 – 我是否需要Monad变换器以及如
我有一个monadic类型的Exp,我想构建一个解析为这样一个值的解析器.以下代码有效,但是我能做些更好/更酷的事情吗?
def grid(x: Int,y: Int): Problem = ??? def expInt: Parser[Exp[Int]] = ??? def grid: Parser[Exp[Problem]] = for{ ex ~ _ ~ ey <- "grid(" ~> expInt ~ "," ~ expInt <~ ")" } yield for{ x <- ex y <- ey } yield grid(x,y) 我听说过monad变形金刚,但仍然有点害怕Scalaz 7的奇怪的导入系统.有人可以回答是否 >我可以使用monad变换器和 解决方法
首先是简单的部分 – “怪异”的导入系统:
import scalaz._,Scalaz._ 就这样.这将永远有效(当然,除非是名称冲突,但这对任何库来说都是可能的并且易于解决),没有人会因为没有使用新的单点菜单导入而瞧不起你,这主要是关于文档的. monad变换器的基本模式是你有一个WhateverT [F [_],…]类型类,它有一个名为runWhateverT(或只是run)的方法返回一个F [Whatever […]]. 在这种情况下,看起来你想要最终得到一个Parser [Exp],这表明你需要自己的ExpT [F [_]]变换器.我不会从有关如何实现它的细节开始(当然,这取决于你的monad的语义),但是将使用Scalaz的OptionT给出一个例子: import scala.util.parsing.combinator._ import scalaz._,Scalaz._ object MyParser extends RegexParsers { implicit val monad = parserMonad(this) def oddNumber: OptionT[Parser,Int] = OptionT.optionT( "d+".r ^^ (_.toInt) ^^ (i => (i % 2 != 0) option i) ) def pairOfOdds: OptionT[Parser,(Int,Int)] = for { _ <- literal("(").liftM[OptionT] x <- oddNumber _ <- literal(",").liftM[OptionT] y <- oddNumber _ <- literal(")").liftM[OptionT] } yield (x,y) def apply(s: String) = parse(pairOfOdds.run,s) } 有关我们为什么需要隐式val monad = …行的讨论,请参见my question here. 它的工作原理如下: scala> MyParser("(13,43)") res0: MyParser.ParseResult[Option[(Int,Int)]] = [1.9] parsed: Some((13,43)) scala> MyParser("(13,42)") res1: MyParser.ParseResult[Option[(Int,Int)]] = [1.8] parsed: None 请注意,oddNumber.run会给我们一个Parser [Option [Int]],它将解析一串数字并返回Some(i)(如果它们代表奇数)或None(如果它们是偶数). 我们实际上并没有打算调用oddNumber.run,但是,在这种情况下 – 我们使用monad变换器的事实意味着我们可以用一个提升的Parser动作(这里的文字(…))组成oddNumber单身理解. 这里的语法是丑陋的 – 例如,我们失去了很好的?组合器和从String到Parser [String]的隐式转换,但是如果我们想要的话,我们可以很容易地编写这些东西的提升版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- twitter-bootstrap – Bootstrap:使用图标问题折叠/解除
- AngularJS----Post
- Shell开发批量创建Linux账户和随机8位数密码
- Bash的vim模式,不是vi
- twitter-bootstrap – 如何获取twitter启动模式关闭(初次启
- bash – 如何判断“find”命令的输出是否为空?
- angularjs – 如何测试必须使用testacular和jasmine呈现的H
- Get the parameter of webservice xml
- twitter-bootstrap – 如何在Bootstrap 3中创建1/5列网格
- scala – 为什么不允许在方法内重载方法(例如重载闭包)?