首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala书中的函数式编程:如何运行第9章的内联示例?

Scala书中的函数式编程:如何运行第9章的内联示例?
EN

Stack Overflow用户
提问于 2018-12-26 20:46:48
回答 1查看 240关注 0票数 1

我正在研究Scala中的函数式编程的第9章( Paul和Rúnar的Manning书)。本章有一些内联的例子,例如在练习9.1之后介绍的下列例子:

代码语言:javascript
复制
char('a').many.slice.map(_.size) ** char('b').many1.slice.map(_.size)

在实现了这些方法之后,我无法在scala中运行这个示例。代码可以找到这里

我做了以下工作来启动这个程序:

代码语言:javascript
复制
./sbt
> ~exercises/console
scala> import fpinscala.parsing._

运行简单的char('a')会给出以下错误:

代码语言:javascript
复制
scala> char('a')
<console>:18: error: not found: value char
       char('a')
       ^

我对scala并不熟悉,所以我可能错过了一些东西。我应该能够从这样的特性在repl运行方法吗?如果是的话,我遗漏了什么?在其他章节中,我试图尽快修改代码,以便对概念有一种感觉,并尝试使用API。但是,目前我无法运行最简单的内联示例。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-26 21:38:14

类型参数Parser[+_]在几乎整个章节中都是抽象的。只有在练习9.12中,您才应该尝试提出自己的实现,并且只在9.6.2中提供了一个可能的解决方案。

在此之前,如果您希望尝试为某些类型的Parser[A]生成A的方法的实现,则有几种可能性。

  • 将它们直接添加到Parsers特性中。在那里,您可以使用所有其他方法,例如char
  • 将代码参数化到所有可能的类型构造函数Parser[+_]上,如9.4页第158页所示。本节以免责声明开始,即“我们还没有代数的实现”,但这并不是必需的,因为实现假设是稍后将提供的参数: def jsonParser]:ParserJSON ={ import P._ // now char可用。??? 这里与您的代码一起工作: def myParser] ={ P._ char('a').many.slice.map(_.size) ** char('b').many1.slice.map(_.size) }
  • 或者,只需通过另一个特性扩展Parsers,仍然保留Parser[+_]抽象: 特质MyParser[Parser+_]扩展ParsersParser { def ab = char('a').many.slice.map(_.size) ** char('b').many1.slice.map(_.size) }

下面是您自己的代码,其中有两个绝对编译的示例:

代码语言:javascript
复制
import language.higherKinds
import language.implicitConversions 

trait Parsers[Parser[+_]] { self => // so inner classes may call methods of trait
  def run[A](p: Parser[A])(input: String): Either[ParseError,A]

  implicit def string(s: String): Parser[String]
  implicit def operators[A](p: Parser[A]) = ParserOps[A](p)
  implicit def asStringParser[A](a: A)(implicit f: A => Parser[String]):
    ParserOps[String] = ParserOps(f(a))

  def char(c: Char): Parser[Char] =
    string(c.toString) map (_.charAt(0))

  def or[A](s1: Parser[A], s2: Parser[A]): Parser[A]
  def listOfN[A](n: Int, p: Parser[A]): Parser[List[A]]

  def many[A](p: Parser[A]): Parser[List[A]]
  def slice[A](p: Parser[A]): Parser[String]

  def many1[A](p: Parser[A]): Parser[List[A]] =
    map2(p, many(p))(_ :: _)


  def product[A,B](p: Parser[A], p2: Parser[B]): Parser[(A,B)]

  def map[A,B](a: Parser[A])(f: A => B): Parser[B]

  def map2[A,B,C](p: Parser[A], p2: Parser[B])(f: (A,B) => C): Parser[C] =
    map(product(p, p2))(f.tupled)


  def succeed[A](a: A): Parser[A] =
    string("") map (_ => a)

  case class ParserOps[A](p: Parser[A]) {
    def |[B>:A](p2: Parser[B]): Parser[B] = self.or(p,p2)
    def or[B>:A](p2: => Parser[B]): Parser[B] = self.or(p,p2)
    def many = self.many(p)

    def map[B](f: A => B): Parser[B] = self.map(p)(f)

    def slice: Parser[String] = self.slice(p)
    def many1: Parser[List[A]] = self.many1(p)

    def **[B](p2: => Parser[B]): Parser[(A,B)] =
      self.product(p,p2)

    def product[A,B](p: Parser[A], p2: Parser[B]): Parser[(A,B)] = self.product(p, p2)
    def map2[A,B,C](p: Parser[A], p2: Parser[B])(f: (A,B) => C): Parser[C] = self.map2(p, p2)(f)
  }

}

case class Location(input: String, offset: Int = 0) {

  lazy val line = input.slice(0,offset+1).count(_ == '\n') + 1
  lazy val col = input.slice(0,offset+1).reverse.indexOf('\n')

  def toError(msg: String): ParseError =
    ParseError(List((this, msg)))

  def advanceBy(n: Int) = copy(offset = offset+n)

  /* Returns the line corresponding to this location */
  def currentLine: String = 
    if (input.length > 1) input.lines.drop(line-1).next
    else ""
}

case class ParseError(stack: List[(Location,String)] = List(),
                      otherFailures: List[ParseError] = List()) {
}

object Parsers {

}

def myParser[P[+_]](P: Parsers[P]) = {
  import P._
  char('a').many.slice.map(_.size) **
  char('b').many1.slice.map(_.size)
}

trait MyParser[P[+_]] extends Parsers[P] {
  def ab = 
    char('a').many.slice.map(_.size) **
    char('b').many1.slice.map(_.size)
}

注意,ParserOps已经被修改:在一些方法中有冗余参数Ap

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53937002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档