Reputation: 1550
I have written the following part of code to parse RDD type and Float in an expression. To parse an arithmetic expression consisting float and RDD like: "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! Note that if I use "Any" it is not able to parse the RDD.
Upvotes: 0
Views: 159
Reputation: 21700
It wants an Either
instead of a Float
, so you give it an 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
:
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. 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.
On another hand, I think you'll get a similar error message later with
pathxml. Fix it in a similar manner, except with Right
instead of Left
.
Upvotes: 1