What's the difference between ArrayBuffer.addOne and ArrayBuffer.append? - scala

2.13.3 API says:
def addOne(elem: A): ArrayBuffer.this.type
Adds a single element to this array buffer.
final def append(elem: A): ArrayBuffer.this.type
Appends the given elements to this buffer.
They seem to do the exact same thing?

They are the same thing. ArrayBuffer is a descendent of Buffer, which defines append:
#`inline` final def append(elem: A): this.type = addOne(elem)
addOne is implemented in ArrayBuffer as part of its implementation towards Growable.
See: Buffer.scala.

Related

Scala REPL truncates the output

I would like to know if is there any way to avoid that Scala REPL truncates the output by setting a environment variable or whatever?
Example
scala> typeOf[Iterator[_]].members.mkString("\n")
res6: String =
override def toString(): String
def toStream: scala.collection.immutable.Stream[A]
def toIterator: Iterator[A]
def toTraversable: Traversable[A]
def sameElements: <?>
def copyToArray[B >: A](xs: Array[B],start: Int,len: Int): Unit
def patch: <?>
def duplicate: <?>
def length: <?>
def sliding$default$2: <?>
def sliding: <?>
def grouped: <?>
class GroupedIterator extends
def buffered: <?>
def indexOf: <?>
def indexOf: <?>
def indexWhere: <?>
def indexWhere: <?>
def find(p: A => Boolean): Option[A]
def contains: <?>
def exists(p: A => Boolean): Boolean
...
I would like to see all the content.
Thanks in advance.
According to source and retronym
/** The maximum length of toString to use when printing the result
* of an evaluation. 0 means no maximum. If a printout requires
* more than this number of characters, then the printout is
* truncated.
*/
var maxPrintString = config.maxPrintString.option getOrElse 800
where
val maxPrintString = int("scala.repl.maxprintstring")
hence start REPL like so
scala -Dscala.repl.maxprintstring=0
to have no truncation.
Addressing the comment, intp.isettings seems to have been removed in Scala 2.13 by REPL: decouple the UI (shell) from the compiler [ci: last-only] #5903. There exists TODO which states:
// TODO bring back access to shell features from the interpreter?
// The repl backend has now cut its ties to the shell, except for the ReplReporter interface
// Before, we gave the user access to: repl, reader, isettings (poor name), completion and history.
// We could bring back some of this functionality if desired by adding it to ReplReporter
hence in Scala 2.13 use -Dscala.repl.maxprintstring approach, however setting in from inside REPL should work pre-2.13
scala> $intp.isettings.maxPrintString = 0
A workaround is to print the string directly:
println(res6)

Task[List[List[A]]] to Task[A] if list has elements

I have a method which returns Task[List[List[A]]] and I need to transform to Task[A] if the list is greater than 0
def method():Task[List[List[A]]] = {}
val d:Task[List[A]] = method().map(_.flatten)
How to get Task[A] is a list of A if the inner method has more than 0 elements
I am able to convert to Task[List[A]] as you can see above
You're flattening the List[List[A]] into a List[A] in the intuitive way, all wrapped in a Task. If you provide the method to go from a List[A] to an A (edit: see below), then you can call it from a map on the task as follows.
def method():Task[List[List[A]]] = {}
def listToItem(list: List[A]): A = ???
def d: Task[A] = method().map(_.flatten).map(listToItem(_))
You say that you want listToItem to take the first element of the list. Unfortunately, such a function wouldn't know what to do if the list were empty. You could use list.head, which will throw an exception if the list is empty, or you could use list.headOption, which will return an Option[T] rather than T.

Why is "contains" implemented in Seq, but not in Iterable or Traversable? [duplicate]

I would like to call 'contains' on my Iterables :-)
The reason Iterable does not have a contains method is because the way it is defined can have direct consequences on variance. Basically, there are two type signatures that make sense for it:
def contains(v: Any): Boolean
def contains(v: A): Boolean
The second definition has increased type safety. However, A, which is the type parameter of collection, appears in a contra-variant position, which forces the collection to be invariant. It could be defined like this:
def contains[B >: A](v: B): Boolean
but that wouldn't offer any improvement over the first signature, using Any.
As a consequence of this, you'll see that immutable.Seq is co-variant and uses the first signature, while immutable.Set is invariant and uses the second signature.
I don't know why contains is not defined on Iterable or TraversableOnce, but you could easily define it yourself:
class TraversableWithContains[A](underlying: TraversableOnce[A]) {
def contains(v: Any): Boolean =
underlying.exists(_ == v)
}
implicit def addContains[A](i: Iterable[A]) = new TraversableWithContains(i)
and use it as if it were defined on Iterable:
val iterable: Iterable[Int] = 1 to 4
assert(iterable.contains(3))
assert(!iterable.contains(5))

Cannot construct a collection

I have a Stream of data and I want to throw everything away except for the final n elements. If the input doesn't have enough elements then the resulting stream is padded with None. This is what I came up with:
def lastN[T](in: Stream[T], len: Int): Stream[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[Stream]
I chose Vector for the internal buffer because of its tail and append performance characteristics.
This all works fine. Perhaps there's a better way? [Note: There's always a better way.]
But suppose Iterator is a more appropriate representation of the input data? No problem, just replace the 3 mentions of Stream with Iterator and it all works.
OK, so why not either/both?
I was hoping I could do something like this:
import scala.language.higherKinds
def lastN[T, C[U] <: TraversableOnce[U] ](in: C[T], len: Int): C[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[C]
Alas, no go.
error: Cannot construct a collection of type C[Option[T]] with
elements of type Option[T] based on a collection of type Nothing.
I've tried futzing with CanBuildFrom directly but I'm just not coming up with the magic formula.
I think it's more natural to use Queue as an internal buffer. It's more semantically suitable for this sort of processing and scala.collection.immutable.Queue is implemented with two Lists and may actually be more efficient than Vector (you'd have to make a measurement to find out if that's the case of course). Otherwise the API stays completely the same: you can just replace the mention of Vector with Queue.
As for CanBuildFrom, it's used in your code to call the to method. You can consult its full signature to find out what CanBuildFrom you'd have to request:
def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, A, Col[A]]): Col[A]
So, you would need CanBuildFrom[Nothing, Option[T], C[Option[T]]].
Putting it all together a possible implementation looks like this:
import scala.collection.generic.CanBuildFrom
import scala.collection.immutable.Queue
def lastN[T, C[U] <: TraversableOnce[U]](in: C[T], len: Int)(
implicit cbf: CanBuildFrom[Nothing, Option[T], C[Option[T]]]
): C[Option[T]] =
in.foldLeft(Queue.fill(len)(None: Option[T]))(_.tail :+ Option(_)).to[C]
As for your comment, the compiler knows that to call to it needs CanBuildFrom[Nothing, Option[T], C[Option[T]]], but it can't automatically find an implicit argument with abstract types.
But if you put a request CanBuildFrom[Nothing, Option[T], C[Option[T]]] in the lastN signature, then when you call for example lastN(Vector(1,2,3), 2), the compiler knows that C is Vector, and T is Int, so it has to pass a CanBuildFrom[Nothing, Option[Int], Vector[Option[Int]]].
Here all types are concrete and the compiler can find a relevant instance of CanBuildFrom using the usual implicit lookup rules. I believe, it will find one in the companion object of Vector in this example.
If you want to take the last N elements of an Iterable, you can use the takeRight function. This should work for any collection that inherits from Iterable, so it will work for Stream. Unfortunately, it has been pointed out that this does not work for Iterator.
def lastN[T](in: Iterable[T], n: Int) = in.takeRight(n)
Traversable, the superclass of Iterator, does have a toIterable function you can use though. If you really want to make it as generic as possible, you can try:
def lastN[T](in: Traversable[T], n: Int) = in.toIterable.takeRight(n)

Why does Iterator have a contains method but Iterable does not, in Scala 2.8?

I would like to call 'contains' on my Iterables :-)
The reason Iterable does not have a contains method is because the way it is defined can have direct consequences on variance. Basically, there are two type signatures that make sense for it:
def contains(v: Any): Boolean
def contains(v: A): Boolean
The second definition has increased type safety. However, A, which is the type parameter of collection, appears in a contra-variant position, which forces the collection to be invariant. It could be defined like this:
def contains[B >: A](v: B): Boolean
but that wouldn't offer any improvement over the first signature, using Any.
As a consequence of this, you'll see that immutable.Seq is co-variant and uses the first signature, while immutable.Set is invariant and uses the second signature.
I don't know why contains is not defined on Iterable or TraversableOnce, but you could easily define it yourself:
class TraversableWithContains[A](underlying: TraversableOnce[A]) {
def contains(v: Any): Boolean =
underlying.exists(_ == v)
}
implicit def addContains[A](i: Iterable[A]) = new TraversableWithContains(i)
and use it as if it were defined on Iterable:
val iterable: Iterable[Int] = 1 to 4
assert(iterable.contains(3))
assert(!iterable.contains(5))