How to solve type mismatch when compiler finds Serializable instead of the match type?
Asked Answered
W

1

8

I have have the following parser to parse arithmetic expressions containing Float and RDD :

 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)

Getting the following error:

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

I am new in Scala and don/t know how I can solve this error

Weighin answered 12/7, 2015 at 19:55 Comment(0)
U
20

Serializable (or similarly Product, or both together) is almost always an indication that you're trying to treat two types as the same when they're not. For example:

scala> if (true) "a" else List(1)
res0: java.io.Serializable = a

The type of a conditional expression is the least upper bound of the types of its two branches—i.e. the most specific type the branches have in common. Here we have a String and a List[Int], which are both instances of AnyRef, but otherwise don't have anything in common besides being Serializable. The fact that they're both Serializable is more specific than the fact that they're both subtypes of AnyRef, so that's the inferred type.

The type of a sequence is inferred similarly:

scala> List("a", "b", "c", 'd)
res1: List[java.io.Serializable] = List(a, b, c, 'd)

In general any time you see Serializable, you should start hunting for something whose type isn't the same as its neighbors or siblings.

In your case pathxml | num is going to be the least upper bound of Parser[RDDThing] and Parser[Float \/ RDDThing], which is again Parser[Serializable]. You should be able to fix this by lifting pathxml into the larger type in your factor2 definition with pathxml.map(_.right) | num.

Ure answered 12/7, 2015 at 21:57 Comment(3)
Thank you for the complete explanation. I did the suggestion and changed the code, I am getting the following error now: type mismatch found"Product with Serializable" why is that?!Weighin
@Rubbic What happens if you try adding a new (possibly temporary) val for pathxml.map(_.right)? Can you type that as Parser[Float \/ RDDThing]? You might need to use something like pathxml.map(_.right[Float]).Ure
if I add "[Float]" it will give me the following error : method right of type scala.util.Either.RightProjection[Float,org.apache.spark.rdd.RDD[(Int, Array[Float])]] does not take type parameters.Weighin

© 2022 - 2024 — McMap. All rights reserved.