How to define a list of lists in Scala?

2020-03-13 07:29发布

问题:

I would like to create a storage for the following type:

List(List(2.3,1.1),List(2.2, 1))

But if I do the following:

var y = List(List (1.0, 2.2), List(2, 1.1, -2.1))

then it creates as List[AnyVal] and gives me error if I try to perform math operation:

y(0)(0) * 2         // Error - value '2' is not a member of AnyVal

回答1:

In both of your examples one list contains one number that is an Int (last 1 in the first case and 2 as the first element of the second list), the rest of the numbers are Doubles. Therefore the inferred type of the list elements will be AnyVal, which is the first common supertype of them, so your outer list will become List[List[AnyVal]].

If you also try it with scala 2.8 then it should use Numeric instead of AnyVal, as it became the supertype of both Double and Int. Most numeric operations (multiplication in your case) will also work on them.

To fix your problem with 2.7.x simply use Doubles for these values (1.0 or 1D).

Explicitly declaring the type as List[List[Double]] will probably also help. In this case the Int values you gave will be converted to Doubles.



回答2:

You may find this link useful: http://debasishg.blogspot.com/2009/01/higher-order-abstractions-in-scala-with.html

From the link above here is an example of making a list of lists:

val brs: List[List[String]] =
  List(List("dave", "john", "sam"), List("peter", "robin", "david"), List("pras", "srim"))

So, for your problem you may want to have:

var y : List[List[Float]] = ...

This way you remove any problems with type inference.



回答3:

Couple of remarks:

F:\prog\scala\scala-2.8.0.r18341-b20090718020201\bin>scala
Welcome to Scala version 2.8.0.r18341-b20090718020201 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> var z = List(List (1.0, 2.2), List(2, 1.1, -2.1))
z: List[List[AnyVal]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))

scala> var z = List(List (1.0f, 2.2f), List(2f, 1.1f, -2.1f))
z: List[List[Float]] = List(List(1.0, 2.2), List(2.0, 1.1, -2.1))

Meaning, like the question "Java: my method wants the double type instead of float?":

The 'f' at the end of the number makes it a float instead of a double.
Java won't automatically narrow a double to a float.


scala> var z = (1.0f :: 2.2f :: Nil) :: (2f :: 1.1f :: -2.1f :: Nil) :: Nil
z: List[List[Float]] = List(List(1.0, 2.2), List(2.0, 1.1, -2.1))

works too


Just adding the explicit type would not be enough:

scala> var z2 : List[List[Float]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))
<console>:4: error: type mismatch;
 found   : Double(1.0)
 required: Float
       var z2 : List[List[Float]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))
                                              ^
<console>:4: error: type mismatch;
 found   : Double(2.2)
 required: Float
       var z2 : List[List[Float]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))
                                                   ^
<console>:4: error: type mismatch;
 found   : Double(1.1)
 required: Float
       var z2 : List[List[Float]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))
                                                                 ^
<console>:4: error: type mismatch;
 found   : Double(-2.1)
 required: Float
       var z2 : List[List[Float]] = List(List(1.0, 2.2), List(2, 1.1, -2.1))
                                                                      ^

That is the same with one single variable:

scala> var f : Float = -2.1
<console>:4: error: type mismatch;
 found   : Double(-2.1)
 required: Float
       var f : Float = -2.1
                       ^

scala> var f : Float = -2.1f
f: Float = -2.1


回答4:

This seems to have been fixed in Scala 2.9

Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> var y = List(List (1.0, 2.2), List(2, 1.1, -2.1))
y: List[List[Double]] = List(List(1.0, 2.2), List(2.0, 1.1, -2.1))

scala> y(0)(0) * 2
res0: Double = 2.0


回答5:

var y:List[List[Double]] = List(List (1.0, 2.2), List(2, 1.1, -2.1))

y(0)(0)*2


标签: scala