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)
Related
I want to split a string delimited by commas and use the result as either a Seq or a Set:
def splitByComma(commaDelimited: String): Array[String]
= commaDelimited.trim.split(',')
def splitByCommaAsSet(commaDelimited: String): Set[String]
= splitByComma(commaDelimited).toSet
def splitByCommaAsSeq(commaDelimited: String): Seq[String]
= splitByComma(commaDelimited).toSeq
val foods = "sushi,taco,burrito"
val foodSet = splitByCommaAsSet(foods)
// foodSet: scala.collection.immutable.Set[String] = Set(sushi, taco, burrito)
val foodSeq = splitByCommaAsSeq(foods)
// foodSeq: Seq[String] = List(sushi, taco, burrito)
However, this is quite repetitive. Ideally, I would want to have something like genericSplitByComma[Set](foods) that just returns a Set when I pass Set in, and returns a Seq when I pass Seq.
#KrzysztofAtłasik's answer works great for Scala 2.12.
This is a solution for 2.13. (Not completely sure if this is the best way).
import scala.collection.Factory
import scala.language.higherKinds
def splitByComma[C[_]](commaDelimited: String)(implicit f: Factory[String, C[String]]): C[String] =
f.fromSpecific(commaDelimited.split(","))
// Or, as Dmytro stated, which I have to agree looks better.
commaDelimited.split(",").to(f)
Which you can use like this:
splitByComma[Array]("hello,world!")
// res: Array[String] = Array(hello, world!)
splitByComma[Set]("hello,world!")
// res: Set[String] = Set(hello, world!)
splitByComma[List]("hello,world!")
// res: List[String] = List(hello, world!)
There's a method in Scala called to which can transform arbitrary collection to another as long as there is typeclass called CanBuildFrom in scope.
import scala.collection.generic.CanBuildFrom
import scala.languageFeature.higherKinds
def genericSplitByComma[S[_]](s: String)(implicit cbf: CanBuildFrom[Nothing, String, S[String]]): S[String] = {
s.split(",").to[S]
}
genericSplitByComma[Set]("Hello, hello") //Set(Hello, hello)
genericSplitByComma[List]("Hello, hello") //List(Hello, hello)
genericSplitByComma[Array]("Hello, hello") //Array(hello, world!)
We don't need to constrain S[_] because this function won't compile if there is no suitable CanBuildFrom in scope. For example, this will fail:
genericSplitByComma[Option]("Hello, hello")
Below will also fail because our type constructor S[_] accepts only one type argument and the map expects two:
genericSplitByComma[Map]("Hello, hello")
As Luis Miguel Mejía Suárez and Dmytro Mitin noticed, there was major refactor in collections in just-released Scala 2.13, so it will work up to Scala 2.12.
There's a simple workaround for this. Not exactly the requested syntax but just as concise and it should be 2.13 compatible.
def simpleSplitByComma(coll :Iterable[String]) =
coll.flatMap(_.trim.split(","))
simpleSplitByComma(Set("hello,world")) //res0: Set(hello, world)
simpleSplitByComma(Seq("bellow,world")) //res1: List(bellow, world)
simpleSplitByComma(Array("fellow,old")) //res2: ArrayBuffer(fellow, old)
simpleSplitByComma(Stream("end,of,the,world")) //res3: Stream(end, ?)
I have a large dataset and the rowId is Long type.
It need to indicate whether one row is in some special set.
I found the BitSet more efficient for memory and network transport, but unlucky that the max value BitSet can hold is Int.
Is there some alternate way? (using boolean[]?)
Thanks
The nature of BitSet makes it so that they can easily broken down and merged together to make network transport easy depending on what you are trying to achieve exactly.
You can always build your own however:
object BitSet extends BitSetFactory[BitSet] {
val empty: BitSet = immutable.BitSet.empty
def newBuilder = immutable.BitSet.newBuilder
implicit def canBuildFrom: CanBuildFrom[BitSet, Long, BitSet] = bitsetCanBuildFrom
}
trait BitSetFactory[Coll <: BitSet with BitSetLike[Coll]] {
def empty: Coll
def newBuilder: Builder[Long, Coll]
def apply(elems: Long*): Coll = (empty /: elems) (_ + _)
def bitsetCanBuildFrom = new CanBuildFrom[Coll, Long, Coll] {
def apply(from: Coll) = newBuilder
def apply() = newBuilder
}
}
trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Long]] extends SortedSetLike[Long, This] { self =>
etc...
This is a follow up to my previous question.
Suppose I need to write a function validate in order to make sure that a given list of strings consists of "a", "b", and one or more "c".
def validate(ss: List[String]): Either[NonEmptyList[MyError], Unit] = ???
Suppose I have three functions to check if a given string is "a", "b", or "c":
def validateA(str: String): Either[MyError, Unit] = ???
def validateB(str: String): Either[MyError, Unit] = ???
def validateC(str: String): Either[MyError, Unit] = ???
How to compose those functions to implement validate ?
One solution is a "parser combinators" approach. Define a monad instance for type Validator = Either[NonEmptyList[MyError], List[String]], combinators like oneOrMore similar to parser combinators etc.
I am wondering whether there is an easier solution.
I suggest you to leverage cats Validated.
Let's define some helper methods, if you really don't want to change your validateT methods signatures:
def validateA_(str: String): ValidatedNel[MyError, Unit] = validateA(str).toValidatedNel
def validateB_(str: String): ValidatedNel[MyError, Unit] = validateB(str).toValidatedNel
def validateC_(str: String): ValidatedNel[MyError, Unit] = validateC(str).toValidatedNel
Then you can implement a validate_ helper function:
import cats.data.Validated.{ invalidNel, valid }
def validate_(ss: List[String]): ValidatedNel[MyError, Unit] = ss match {
case a :: b :: c if c.nonEmpty =>
validateA_(a) combine validateB_(b) combine c.traverseU_(validateC_)
case _ => invalidNel(MyError(???)) //List too short
}
And finally implement your validate function as:
def validate(ss: List[String]): Either[NonEmptyList[MyError], Unit] =
validate_(ss).toEither
Assumptions: the input list is sorted and if it is shorter than 3 elements a specific error (e.g. list too short) is acceptable.
Looks like you could make use of Scalactic, which allows one to accumulate errors without short-circuiting the whole validation process.
This example looks quite similar to what you are trying to do. Check it out!
I have the following use case which occurs often in my code:
A Collection[A]
An implicit conversion A to B
and I want to obtain a collection of B. I can use implicitly like the following:
case class Items(underlying:List[B])
import B._
def apply(a:List[A]):Items = {
val listOfB= a.map {implicitly[A=>B]}
Items(listOfB)
}
What is the most elegant way to do that in Scala, maybe with the help of Scalaz of doing the same?
Edit: the goal of my question is to find an idiomatic way, a common approach among libraries/developers. In such a sense developing my own pimp-my-library solution is something I dislike, because other people writing my code would not know the existence of this conversion and would not use it, and they will rewrite their own. I favour using a library approach for this common functions and that's why I am wondering whether in Scalaz it exists such a feature.
It's pretty straightforward if you know the types. First implicit conversion from A to B:
implicit def conversion(a: A): B = //...
then you need implicit conversion from List[S] to List[T] where S and T are arbitrary types for which implicit conversion from S to T exists:
implicit def convList[S, T](input: List[S])(implicit c: S => T): List[T] =
input map c
This should then work:
val listOfA: List[A] = //...
val listOfB: List[B] = listOfA
which is resolved by the compiler to:
val listOfB: List[B] = convList(listOfA)(conversion)
where S is A and T is B.
I wouldn't use an implicit conversion here, but a view bound in the class:
case class Foo(x: Int)
case class Bar(y: Int)
implicit def foo2Bar(foo: Foo) = Bar(foo.x)
case class Items[A <% Bar](xs: List[A]) {
def apply(x: Int): Bar = xs(x)
}
You can now create an instance of Items with a list of Foo and internally use them, as if they were Bars.
scala> Items(List(Foo(1)))
res8: Items[Foo] = Items(List(Foo(1)))
scala> res8(0)
res9: Bar = Bar(1)
edit:
Some clarification, on why I would not use an implicit conversion:
Implicit conversions can be dangerous, when they are in scope and accidentally convert things, that they shouldn't convert. I would always convert stuff explicitly or via view bounds, because then I can control it, also implicit conversion may shrink the size of your code, but also makes it harder to understand for others. I would only use implicit conversion for the 'extend my library' pattern.
edit2:
You could however add a method to the collection types, that does this conversion, if such a method is in scope:
trait Convertable[M[A], A] {
def convertTo[B](implicit f: A => B): M[B]
}
implicit def list2Convertable[A](xs: List[A]) = new Convertable[List, A] {
def convertTo[B](implicit f: A => B) = xs.map(f)
}
scala> implicit def int2String(x: Int) = x.toString
int2String: (x: Int)String
scala> List(1,2,3).convertTo[String]
res0: List[String] = List(1, 2, 3)
Instead of using another implicit conversion here, I would probably use a typeclass instead, but I think you get the basic idea.
Works starting with Scala 2.10:
implicit class ListOf[A](val list: List[A]) {
def of[B](implicit f: A => B): List[B] = list map f
}
implicit def int2String(i: Int) = i.toString
// Usage
List(1,2,3).of[String]
In my code, I'm using a more general version adapted from Tomasz' solution above which handles all Traversable instances
/** Implicit conversion for Traversable instances where the elements are convertable */
implicit def convTrav[S, T, I[S] <: Traversable[S]](input: I[S])(implicit c: S => T): I[T] =
(input map c).asInstanceOf[I[T]]
(This is working for me, although I'm keen to know if any more experienced Scala programmers think this is a bad idea for any reason, apart from the usual caveats about implicit conversions)
Is there something I've got wrong with the following fragment:-
object Imp {
implicit def string2Int(s: String): Int = s.toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f("666")
}
}
I get the following from the 2.8 compiler:-
Information:Compilation completed with 1 error and 0 warnings
Information:1 error
Information:0 warnings
...\scala-2.8-tests\src\Imp.scala
Error:Error:line (4)error: type mismatch;
found : String
required: ?{val toInt: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method string2Int in object Imp of type (s: String)Int
and method augmentString in object Predef of type (x:String)scala.collection.immutable.StringOps
are possible conversion functions from String to ?{val toInt: ?}
implicit def string2Int(s: String): Int = s.toInt
What is happening is that Java does not define a toInt method on String. In Scala, what defines that method is the class StringOps (Scala 2.8) or RichString (Scala 2.7).
On the other hand, there is a method toInt available on Int as well (through another implicit, perhaps?), so the compiler doesn't know if it is to convert the string to StringOps, through the defined implicit, or to Int, through your own implicit.
To solve it, call the implicit explicitly.
object Imp {
implicit def string2Int(s: String): Int = augmentString(s).toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f("666")
}
}
There is already an implicit conversion in scope, from scala.Predef. You don't need to declare your own implicit conversion to add a toInt method to a String. You have 3 options (I'd go for the last one!):
Change your method name to something like asInt
Unimport the conversion in Predef
Don't bother defining your own and use instead the toInt that comes bundled with the scala library
Note that scala will only make use of an in-scope implicit conversion if it is unique.
I think I have a workaround.
If I create a RichString from the String argument, the implicit conversion occurs from RichString to Int using the implicit method I provide (this works for 2.7.x and 2.8). If I remove my implicit I get a type error.
object Imp {
implicit def string2Int(rs: RichString): Int = rs.toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f(new RichString("666"))
println(n)
}
}
I'm still confused as to why both implicits came into scope and clashed when I provided an implicit and as to why the Predef one didn't come into scope when I didn't provide one for String to Int. I suppose the question about an implicit conversion from String to Int remains open.