Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Some(List(1,2,3)).flatten compile?

In Scala 2.9.1, I could do

> Some(List(1,2,3)).flatten
List(1,2,3)

But in Scala 2.10.0,

> Some(List(1,2,3)).flatten
Cannot prove that Seq[Int] <:< Option[B]

I found this closed bug, but I don't understand the verdict, or why it was closed.

(1) Why doesn't this work in Scala 2.10 (apparently by design?)

(2) What is the idiomatic 2.10 equivalent of my 2.9 code?

like image 357
Paul Draper Avatar asked Mar 05 '14 17:03

Paul Draper


People also ask

What does it mean to flatten a list?

This continues onwards, as we add more and more layers. When you convert a list of lists, or a 2-dimensional array, into a one-dimensional array, you are flattening a list of lists. Learn four different ways to do this in this tutorial!

How to enable/disable flattening during logic optimization during compile?

you can use set_flatten command (options are true and false) to enable and disable this behavior during logic optimization (during compile)... By default it is set to be false...

Should flatten function be added to standard library in Python?

Proposals for a flatten function to be added to the standard library appear from time to time on python-dev and python-ideas mailing lists. Python developers usually respond with the following points:

How to flatten the netlist?

the ungroup command removes the hierarchy in the design (netlist) and make it flat.. you can use set_flatten command (options are true and false) to enable and disable this behavior during logic optimization (during compile)...


2 Answers

flatten adopts the type of the outer container. You can't fit a List into an Option, so that doesn't work. Instead, change the type of the outer container first so flattening is possible:

Some(List(1,2,3)).toList.flatten
like image 198
Rex Kerr Avatar answered Nov 08 '22 03:11

Rex Kerr


flatten is really only intended to work on a single monad at a time. That is, it transforms M[M[T]] into M[T], as in List(List(1,2),List(3)).flatten => List(1,2,3). scala.Predef provides implicits to coerce Option[T] into List[T], but not the other way around. While it is somewhat reasonable to treat an Option as a List of zero or one elements, there's no general pattern for Lists with two or more elements.

The other way around, however, is supported for convenience:

List(Some(1),None,Some(2),Some(3)).flatten => List(1, 2, 3)

Edit: i misspoke. it's not an implicit conversion to Option that makes this possible, but rather that Option is traversable. In the api docs, List's flatten is actually:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]
like image 26
Rob Starling Avatar answered Nov 08 '22 03:11

Rob Starling