It is impossible to prove that Unit <: <(T, U)

When trying to remove all Unit - () from the list, I tried to call toMap .

 scala> List((), ()).filter(_ != ()).toMap <console>:8: error: Cannot prove that Unit <:< (T, U). List((), ()).filter(_ != ()).toMap ^ 

What does this error mean?

For a List I would like to create a map of all tuples (String, String) for elements other than Unit, but some of the values ​​may be empty.

 scala> val x = List((), (), (3,4)).filter(_ != ()).toMap <console>:7: error: Cannot prove that Any <:< (T, U). val x = List((), (), (3,4)).filter(_ != ()).toMap ^ scala> val x = List((), (), (3,4)).filter(_ != ()) x: List[Any] = List((3,4)) scala> x.toMap <console>:9: error: Cannot prove that Any <:< (T, U). x.toMap ^ 
+6
source share
3 answers

Oh! Now your other question makes a little more sense. Still not sure what you are doing to create this Unit / Tuple2 mixed list.

This should work:

 List((), (), (3,4)).collect { case [email protected] (_: Int, _: Int) => t }.toMap 

Note that I use variable binding here (matching binding to t ) to return the same Tuple2 instance that we matched than creating a new one.

Using collect , you convert the type of your list from List[Any] to List[(Int, Int)] , which is required by toMap since it expects some List[(A,B)] .


Note. While this answer should work for you, I still think your design is flawed. You would be better off eliminating a major design flaw rather than treating such symptoms.

It seems like this would be good to use the Scala Option type . In this case, your list of samples will become List(None, None, Some((3,4))) , or you can write it as List(None, None, Some(3->4)) for reading (nested parentheses like this can get confused).

If you use Option , then the type of your list will become List[Option[(Int, Int)]] , which should be much nicer than List[Any] . To get rid of None entries and get the desired List[(Int,Int)] , you can simply call flatten :

 List(None, None, Some(3->4)).flatten // res0: List[(Int, Int)] = List((3,4)) List(None, None, Some(3->4)).flatten.toMap // res1: scala.collection.immutable.Map[Int,Int] = Map(3 -> 4) 

However, it will be even better if you can not put None entries on your list at all. If you create this list using Scala for understanding, you can use a protector in your expression to remove invalid elements from the output.

+4
source

This means that the type of the item in the list cannot be considered as a tuple that is required to create a Map. A map, in a sense, is a collection of tuples (and more).

Illustration:

 scala> List(1).toMap <console>:8: error: Cannot prove that Int <:< (T, U). List(1).toMap ^ scala> List(1 -> 2).toMap res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2) 

I can build a map from a list of tuples, but not from a list of single power elements.

Maybe you want to say .map instead of .toMap ?;)

+1
source

All in one go:

 scala> val l2 = List(1 -> 3, (), 4 -> 4, (), 9 -> 4, (), 16 -> 7) l2: List[Any] = List((1,3), (), (4,4), (), (9,4), (), (16,7)) scala> (l2 collect { case (a, b) => (a, b) }).toMap res4: scala.collection.immutable.Map[Any,Any] = Map(1 -> 3, 4 -> 4, 9 -> 4, 16 -> 7) 

Better Typed:

 scala> (l2 collect { case (i: Int, j: Int) => (i, j) }).toMap res5: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 4 -> 4, 9 -> 4, 16 -> 7) 
+1
source

Source: https://habr.com/ru/post/955700/


All Articles