while learning how to use lists:
val oneTwo = List(1, 2)
val threeFour = List(3, 4)
val oneTwoThreeFour = oneTwo :: threeFour //forgot one ":", I really meant to ":::" (concatenate)
val filteredList = oneTwoThreeFour.filter(n => n > 1)
scalac informed me:
Error:Error:line (16)error: value > is not a member of scala.this.Any
val l2 = oneTwoThreeFour.filter(n => n > 1)
Commenting out the offending line and replacing it with
println("oneTwoThreeFour " + oneTwoThreeFour)
yields
oneTwoThreeFour List(List(1, 2), 3, 4)
which clearly shows that the first element is not an Int.
However, the following line compiles:
val filteredList = oneTwoThreeFour.filter(n => n == 1)
probably because '==' is defined for scala.this.Any
January 19, 2009
Subscribe to:
Post Comments (Atom)
2 comments:
Unfortunately, this is a natural consequence of type inference. There's really no way around this sort of thing. In general, the problem with type inference is that it can sometimes divorce the site where the error manifests from its origin. Think about it, if you had to declare `oneTwoThreeFour` explicitly as being of type List[Int], none of this would have happened.
Things are even worse in languages with Hindley-Milner type inference:
fun sum nil i = i
| sum (hd :: tail) i = hd + (sum tail i)
Take this function, and make a two character substitution:
fun sum nil i = i
| sum (hd :: tail) i = hd :: (sum tail i)
The difference is pretty radical and apparent in the type signatures:
-- correct
sum :: int list -> int -> int
-- incorrect
sum :: 'a list -> 'a list -> 'a list
Actually, the second function is one definition of append, but that's beside the point.
When you choose a language with type inference, you are making the deliberate decision to sacrifice some accuracy in your type errors for added convenience. Most of the time this works out, but there are still bizarre problems. Here's another for your viewing pleasure:
val nums = List(1, 2, 3)
nums.foldRight(Nil) { _ :: _ }
The result?
error: type mismatch;
found : List[Int]
required: object Nil
nums.foldRight(Nil) { _ :: _ }
It's not a problem with languages with type inference. It's a problem with type inference itself.
You can go ahead and declare all types in Scala, and this won't happen. Whether that's gaining or losing you time, that's another proposition.
Post a Comment