-
Notifications
You must be signed in to change notification settings - Fork 72
Flatten and interaction between flatMap and Options #48
Conversation
Good to see that it works, but should it continue to work? Should Options be converted implicitly to collections rather than requiring an explicit conversion? |
If we want it to work we could also make |
Then it raises the following question: is it desirable to have |
|
Oh yes, good point… |
the implicit conversion from Option to Iterable as it is in 2.12 is quite annoying, imho. some methods that could/should exist on Option don't - but do exist on Iterable, just with the wrong return type. zip, for example. always good for a surprise, especially as scaladoc says it returns an Option: scala> Some(1) zip Some(2)
res0: Iterable[(Int, Int)] = List((1,2)) |
I would worry that |
I also would be very reluctant to add superclasses to Option. @sjrd has a design to make options unboxed, and we should investigate whether we can adopt this. That would be a significant performance win. But with added superclasses it's not clear we can do it so easily. |
Actually it's pretty clear we can't. At least my design would not accommodate that at all. |
Unboxed options (with |
FTR my proof of concept is at https://github.com/sjrd/scala-unboxed-option |
@sjrd - It's more robust to use sentinels as then you never rely upon the type seen by the compiler. Isn't it slower, though, in the case where types are all known (i.e. the typical case)? Then you don't need to consider the I guess fragility under erasure is sufficiently unacceptable so that a performance hit, even if there, is okay. (Note: I implemented a scheme very like yours with right-unboxed either, but didn't feel like working on macros for long enough to get it all the way across the zero-cost finish-line.) |
Even if the type is known to be
My design lends itself to that kind of optimizations by a general-purpose(-ish) optimizer, after inlining. For example, consider def apply[A](value: A): USome[A] = value match {
case value @ UNone => value.wrap.asInstanceOf[USome[A]]
case value: WrappedNone => value.wrap.asInstanceOf[USome[A]]
case _ => value.asInstanceOf[USome[A]]
} Once inlined, the optimizer can tell that
private def forceGet: A = (self: Any) match {
case none: WrappedNone =>
none.unwrap.asInstanceOf[A]
case _ =>
self.asInstanceOf[A]
} But here, since |
You'd have to do Or you define a separate implicit class that represents a true |
Hi, I rebased this PR and applied the trick suggested by @szeiger: the implicit conversion to |
For some reasons the tests fail under dotty. Any idea of why? |
The test depends on the iteration order of HashSet which is undefined |
Indeed, I just fixed that. |
Why is it different between Scala and Dotty though? It's the same HashSet implementation and hash codes for Ints are identities in both. |
This is based on szeiger:wip/constrained-collections2. I only added the last commit to check that
flatten
would work withIterable[Option[?]]
values. This requiresflatten
to take an implicit view parameter and to define an implicit conversion fromOption[A]
toIterable[A]
(as it is currently the case in 2.12).I also checked that it was possible to use
flatMap
with a function returning anOption[?]
(instead of the expectedIterableOnce[?]
), which is a common pattern I think.