如何在Scala中的一个解析器中解析两种不同的类型?

时间:2015-07-11 22:18:38

标签: scala parsing rdd type-mismatch

我编写了以下部分代码来解析表达式中的RDD类型和Float。解析包含float和RDD的算术表达式,如:" firstRDD + 2" :

def term2: Parser[List[Either[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
def factor2: Parser[Either[Float, RDD[(Int,Array[Float])]]] = pathxml | num  
def pathxml: Parser[RDD[(Int,Array[Float])]] = pathIdent ^^ {s => pathToRDD(s) } //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
def num: Parser[Float] = floatingPointNumber ^^ (_.toFloat)

现在我收到了这个错误:

  [error] type mismatch;
  [error]  found   : ParseExp.this.Parser[Float]
  [error]  required: ParseExp.this.Parser[Either[Float,org.apache.spark.rdd.RDD[(Int, Array[Float])]]]
  [error]   def factor2: Parser[Either[Float, RDD[(Int,Array[Float])]]] = pathxml | num 
  [error]                                                                           ^

我不知道怎么做,除了使用"要么"并且不知道如何解决这种类型的不匹配! 请注意,如果我使用"任何"它无法解析RDD。

1 个答案:

答案 0 :(得分:1)

它需要Either而不是Float,因此您需要Either。 但我们不能简单地从输出中创建值,因为 解析器使用函数,而不是值。

def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => Left(n).toFloat)

并希望它有效。如果它没有,那么走很长的路线:

def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n =>
  val res: Either[Float, RDD[(Int,Array[Float])]] = n.toFloat
  res
)

或scalaz路线(您必须重写代码才能使用\/ 而不是Either

import scalaz._
import Scalaz._

def term2: Parser[List[\/[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
def pathxml: Parser[RDD[(Int,Array[Float])]] = pathIdent ^^ {s => pathToRDD(s) } //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
def num: Parser[\/[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => n.left[RDD[(Int,Array[Float])]].toFloat)
来自scalaz的

leftright几乎可以满足您的期望 - 他们创造一个左或右的价值。您传递给的类型参数 left或right用于构造完整类型,因为值 仅提供左或右类型,但完整的任一类型需要 另一边的类型(右/左),所以另一种类型 也需要通过。

另一方面,我认为您稍后会收到类似的错误消息 pathxml。除非使用Right代替Left,否则请以类似的方式对其进行修复。