Why does cons function called explicity works over Int in Scala?
Question
You can create a new List in Scala using:
1 :: 2 :: Nil
In my understanding this can rewritten to:
Nil.::(2.::(1))
Mainly because :: fixty but if I write:
Nil :: 1 :: 2
I get "value :: is not a member of Int" what is totally expected because in scaladoc Int does not have ::, but I can't understand why if I translate that to:
1.::(2.::(Nil))
It works getting as output:
List(1.0, 2.0)
It looks like scalac auto casts the 1
and 2
to a type different than Int. Is that correct? If it is, why does it happen and which is this strange type?
La solution
This is funny.
Your expression
1.::(2.::(Nil))
is being parsed by the compiler as
1. :: (2. :: (Nil))
which, since ::
is right-associative, is the same as
1. :: 2. :: Nil
which, since 1.
is a valid way of writing a Double
, is the same as
1.0 :: 2.0 :: Nil
which is a legal expression for constructing the List[Double]
List(1.0, 2.0)
Autres conseils
You write that the expression
1 :: 2 :: Nil
can be rewritten as
Nil.::(2.::(1))
This is not quite correct, because 2.
is parsed as a Double
. This could be fixed by adding parenthesis around 2, but then the compiler still complains as class Int
does not support method ::
!
The given expression can be written as
(Nil.::(2)).::(1)
The other expression which you have is
1.::(2.::(Nil))
Here, the compiler parses 1.
and 2.
as doubles, i.e. it eagerly consumes as many characters as possible when reading a token. If you want to avoid that, then you either can put parenthesis around the integers or add a blank between the number and the dot:
1 .::(2 .::(Nil))
(1).::((2).::(Nil))
However, you get an error on these expressions too as ::
is not a member of class Int
(nor a member of any class to which an implicit conversion exists).