Scala
Jump to navigation
Jump to search
Scala Notes
Use of '_'
From - https://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala
import scala._ // Wild card -- all of Scala is imported import scala.{ Predef => _, _ } // Exception, everything except Predef def f[M[_]] // Higher kinded type parameter def f(m: M[_]) // Existential type _ + _ // Anonymous function placeholder parameter m _ // Eta expansion of method into method value m(_) // Partial function application _ => 5 // Discarded parameter case _ => // Wild card pattern -- matches anything val (a, _) = (1, 2) // same thing for (_ <- 1 to 10) // same thing f(xs: _*) // Sequence xs is passed as multiple parameters to f(ys: T*) case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence var i: Int = _ // Initialization to the default value def abc_<>! // An underscore must separate alphanumerics from symbols on identifiers t._2 // Part of a method name, such as tuple getters 1_000_000 // Numeric literal separator (Scala 2.13+)
So...
Existential types
def foo(l: List[Option[_]]) = ...
Higher kinded type parameters
case class A[K[_],T](a: K[T])
Ignored variables
val _ = 5
Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }
Ignored names of self types
trait MySeq { _: Seq[_] => }
Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
Wildcard patterns in interpolations
"abc" match { case s"a$_c" => }
Sequence wildcard in patterns
C(1, 2, 3) match { case C(vs @ _*) => vs.foreach(f(_)) }
Wildcard imports
import java.util._
Hiding imports
import java.util.{ArrayList => _, _}
Joining letters to operators
def bang_!(x: Int) = 5
Assignment operators
def foo_=(x: Int) { ... }
Placeholder syntax
List(1, 2, 3) map (_ + 2)
Method values
List(1, 2, 3) foreach println _
Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _
Default initializer
var x: String = _ // unloved syntax may be eliminated
Other
Match Expressions
def getClassAsString(x: Any): String = x match { case s: String => s + " is a String" case i: Int => "Int" case f: Float => "Float" case l: List[_] => "List" case p: Person => "Person" case _ => "Unknown" }
def isTrue(a: Any) = a match { case 0 | "" => false case _ => true }
// Version 1 - compiles to a tableswitch import scala.annotation.switch class SwitchDemo { val i = 1 val x = (i: @switch) match { case 1 => "One" case 2 => "Two" case _ => "Other" } }
expr match { case List(1,_,_) => "A List with three elements" case List(_ *) => "A List with zero or more elements" case Map(_,_) => "A Map with any Key and Value type" case _ => "Anythiong else" }
Getters and Setters
According to the Scala docs:
Scala does not follow the Java convention of prepending set/get to mutator and accessor methods (respectively). Instead, the following conventions are used:
- For accessors of properties, the name of the method should be the name of the property.
- In some instances, it is acceptable to prepend “is” on a boolean accessor (e.g. isEmpty). This should only be the case when no corresponding mutator is provided.
- For mutators, the name of the method should be the name of the property with “_=” appended.
So:
class Foo { def bar = ... def bar_=(bar: Bar) { ... } def isBaz = ... }
val nums = List(1,2,3,4,5,6,7,8,9) nums filter (_ % 2 == 0) nums reduce (_ + _) nums.exists (_ > 5) nums.takeWhile(_ < 8)
As used in Swift for un-named or unused values:
def getProps = { Config.getHost, Config.getPort, Config.getIp, Config.getMask } val (host, port, ignore1, ignore2) = getProps val (host, port, _, _) = getProps
Types
type StringMatcher = String => (String => Boolean) def starts: StringMatcher = (prefix:String) => _ startsWith prefix ...or... def starts: StringMatcher = (prefix:String) => (s) => s startsWith prefix
Generating Random Strings
One liner:
Random.alphanumeric.take(10).mkString
From - https://alvinalexander.com/scala/creating-random-strings-in-scala/
import scala.annotation.tailrec /** * Examples of different ways to write "random string" methods in Scala. * See the main method for examples of how each method is called. * Created by Alvin Alexander, https://alvinalexander.com */ object RandomStringExamples { def main(args: Array[String]) { println("1: " + randomString(10)) println("2: " + randomStringArray(10)) println("3: " + randomStringRecursive(10).mkString) println("3: " + randomStringRecursive2(10).mkString) println("4: " + randomStringTailRecursive(10, Nil).mkString) println("5: " + randomStringRecursive2Wrapper(10)) println("6: " + randomAlphaNumericString(10)) println("6: " + randomAlphaNumericString(10)) println("6: " + randomAlphaNumericString(10)) println("x2: " + x2(10, ('a' to 'z') ++ ('A' to 'Z'))) } // 1 - a java-esque approach def randomString(length: Int) = { val r = new scala.util.Random val sb = new StringBuilder for (i <- 1 to length) { sb.append(r.nextPrintableChar) } sb.toString } // 2 - similar to #1, but using an array def randomStringUsingArray(length: Int): String = { val r = new scala.util.Random val a = new Array[Char](length) val sb = new StringBuilder for (i <- 0 to length-1) { a(i) = r.nextPrintableChar } a.mkString } // 3 - recursive, but not tail-recursive def randomStringRecursive(n: Int): List[Char] = { n match { case 1 => List(util.Random.nextPrintableChar) case _ => List(util.Random.nextPrintableChar) ++ randomStringRecursive(n-1) } } // 3b - recursive, but not tail-recursive def randomStringRecursive2(n: Int): String = { n match { case 1 => util.Random.nextPrintableChar.toString case _ => util.Random.nextPrintableChar.toString ++ randomStringRecursive2(n-1).toString } } // 4 - tail recursive, no wrapper @tailrec def randomStringTailRecursive(n: Int, list: List[Char]):List[Char] = { if (n == 1) util.Random.nextPrintableChar :: list else randomStringTailRecursive(n-1, util.Random.nextPrintableChar :: list) } // 5 - a wrapper around the tail-recursive approach def randomStringRecursive2Wrapper(n: Int): String = { randomStringTailRecursive(n, Nil).mkString } // 6 - random alphanumeric def randomAlphaNumericString(length: Int): String = { val chars = ('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9') randomStringFromCharList(length, chars) } // 7 - random alpha def randomAlpha(length: Int): String = { val chars = ('a' to 'z') ++ ('A' to 'Z') randomStringFromCharList(length, chars) } // used by #6 and #7 def randomStringFromCharList(length: Int, chars: Seq[Char]): String = { val sb = new StringBuilder for (i <- 1 to length) { val randomNum = util.Random.nextInt(chars.length) sb.append(chars(randomNum)) } sb.toString } def x(length: Int, chars: Seq[Char]): String = { val list = List.range(1, length) val arr = new Array[Char](length) list.foreach{ e => arr(e) = chars(util.Random.nextInt(chars.length)) } list.mkString } // create a fake list so i can use map (or flatMap) def x2(length: Int, chars: Seq[Char]): String = { val tmpList = List.range(0, length) val charList = tmpList.map{ e => chars(util.Random.nextInt(chars.length)) } return charList.mkString } }