如何在 Scala 的一个解析器中解析两种不同的类型?
How to parse two different types in one parser in Scala?
我写了以下部分代码来解析表达式中的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] ^
除了使用 "Either" 之外,我不知道该怎么做,也不知道如何解决这种类型不匹配问题!
请注意,如果我使用 "Any" 它无法解析 RDD。
它想要一个 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 的 left
和 right
几乎可以满足您的期望 -
他们创造了一个左值或右值。您传递给的类型参数
left 或 right 用于构造完整类型,因为值
仅提供左或右类型,但完整的任一种类型都需要
另一侧的类型 (right/left) 也是,所以另一种类型
也需要通过
另一方面,我认为您稍后会收到类似的错误消息
路径xml。以类似的方式修复它,除了 Right
而不是 Left
.
我写了以下部分代码来解析表达式中的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] ^
除了使用 "Either" 之外,我不知道该怎么做,也不知道如何解决这种类型不匹配问题! 请注意,如果我使用 "Any" 它无法解析 RDD。
它想要一个 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 的 left
和 right
几乎可以满足您的期望 -
他们创造了一个左值或右值。您传递给的类型参数
left 或 right 用于构造完整类型,因为值
仅提供左或右类型,但完整的任一种类型都需要
另一侧的类型 (right/left) 也是,所以另一种类型
也需要通过
另一方面,我认为您稍后会收到类似的错误消息
路径xml。以类似的方式修复它,除了 Right
而不是 Left
.