Skip to content

Instantly share code, notes, and snippets.

@peltho
Created June 22, 2019 10:41
Show Gist options
  • Save peltho/0494e54e7997076e5bb562dea88f91ab to your computer and use it in GitHub Desktop.
Save peltho/0494e54e7997076e5bb562dea88f91ab to your computer and use it in GitHub Desktop.
Scala

Scala


Functions

  • Named functions
def foo(x:Int): Int = x + 1
def foo(x:Int): Int = {
  x + 1
}
  • Anonymous functions
(x: Int) => x + 1
  • Partial application
def add(a:Int, b:Int): Int = a + b
val add3 = add(1, _)
add3(2)

// res: Int = 5

_ acts as a an unnamed magical wildcard and has different meanings regarding the context

  • Curried functions
def multiply(a: Int)(b: Int): Int = a * b
val foo = multiply(3) _
foo(2)

// res: Int = 6

Making a function curried :

def multiply(a: Int, b: Int): Int = a * b
val curriedMultiply = (multiply _).curried
val foo = curriedMultiply(2)
foo(3)

// res: Int = 6

Classes

  • Constructor

It's basically code outside of method definitions in class.

class Cat(sex: String) {
  val name: String = if (sex == "male") {
    "pompon"
  } else if (sex == "female") {
    "pomponette"
  } else {
    "giroflée"
  }
}

val cat = new Cat("female")
cat.name

// res: String = pomponette

Traits

If you need a constructor parameter, use an abstract class. Abstract class constructors can take parameters; trait constructors can’t.

Btw a trait is basically the same as an abstract class, you can't implement methods in it. Nevertheless it's preferable to use traits since many of them they can be extended by a given class.

Apply methods

Used to prevent from using new keyword when instantiating a class :

class Foo {}

object FooCompanion {
  def apply() = new Foo
}

val newFoo = FooCompanion()

// res: Foo

Pattern matching

  • Basics
val times = 1

times match {
  case 1 => "one"
  case 2 => "two"
  case _ => "fuck it"
}
times match {
  case i: Int if i == 1 => "one"
  case i: Int if i == 2 => "two"
  case _ => "fuck it"
}

Notice: the type : Int isn't mandatory here and can differ if matching different types

  • Case classes

Case classes are used to conveniently store and match on the contents of a class. You can construct them without using new.

case class Cat(sex: String, breed: String)
val kitty = Cat("female", "maine coon")

New pattern matching with case class:

def catProbableName(cat: Cat) = cat match {
  case Cat("female", "maine coon") => "pomponette"
  case _ => "IDK"
}

Basic data structures

  • Array: val numbers = Array(1, 1, 2, 3)
  • List: val numbers = List(1, 1, 2, 3) They are immutable
  • Set: val numbers = Set(1, 1, 2, 3) res: Set[Int] = Set(1, 2, 3)
  • Tuple: val hostPort = ("localhost", 80) res: hostPort = (String, Int) They can also be defined this way : 1 -> 2 (Int, Int) = (1, 2)
  • Map: `Map("foo" -> "bar")

Functional combinators

  • map exact as a lodash _.each and returns smth:
val numbers = List(1, 2, 3, 4)
numbers.map((i: Int) => i * 2)

//res: List[Int] = List(2, 4, 6, 8)
  • foreach returns nothing
  • flatten:
List(List(1, 2), List(3, 4)).flatten

//res0: List[Int] = List(1, 2, 3, 4)
  • flatMap: nestedNumbers.flatMap(x => x.map(_ * 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment