[英]How to parse two different types in one parser in Scala?
I have written the following part of code to parse RDD type and Float in an expression. 我写了以下代码来解析表达式中的RDD类型和Float。 To parse an arithmetic expression consisting float and RDD like: "firstRDD + 2" :
解析由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)
Now I am getting this error: 现在我收到此错误:
[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] ^
I don't know how to do that except using "Either" and don't know how to solve this type mismatch! 除了使用“ Either”之外,我不知道该怎么做,也不知道如何解决这种类型的不匹配! Note that if I use "Any" it is not able to parse the RDD.
请注意,如果我使用“任何”,则无法解析RDD。
It wants an Either
instead of a Float
, so you give it an Either
. 它需要一个
Either
而不是Float
,因此您给它一个Either
。 But we cannot simply create the value from the output, because the Parser works with functions, not values. 但是我们不能简单地从输出中创建值,因为解析器使用函数而不是值。
def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => Left(n).toFloat)
and hope it works. 希望它能工作。 If it doesn't, go the long route:
如果没有,则走很长的路:
def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n =>
val res: Either[Float, RDD[(Int,Array[Float])]] = n.toFloat
res
)
Or the scalaz route (you'll have to rewrite the code to use \\/
instead of Either
: 或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)
left
and right
from scalaz do pretty much what you would expect - they create a left or a right value. scalaz的
left
和right
几乎可以实现您所期望的-它们创建了left或right值。 The type argument you pass to left or right is used to construct the full type, because the value only provides the left or right type, but the full either type needs the type of the other side (right/left) as well, so the other type needs to be passed as well. 您传递给left或right的type参数用于构造完整类型,因为该值仅提供left或right类型,但是其中一个full类型也需要另一边的类型(right / left),因此其他类型也需要传递。
On another hand, I think you'll get a similar error message later with pathxml. 另一方面,我认为您稍后会在pathxml中收到类似的错误消息。 Fix it in a similar manner, except with
Right
instead of Left
. 以类似的方式修复它,除了用
Right
代替Left
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.