public class User { private final String firstName; private final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public void getLastName() { return this.lastName; } @Override toString() { ... } @Override hashCode() { ... } @Override equals(Object obj) { ... } }
case class User(firstName: String, lastName: String)
def compose[G[_, _]](implicit G0: Bifunctor[G]): Bifunctor[({type λ[α, β]=F[G[α, β], G[α, β]]})#λ] = new CompositionBifunctor[F, G] { implicit def F = self implicit def G = G0 }
trait Category[=>:[_, _]] extends Compose[=>:] { self => def id[A]: A =>: A def empty: PlusEmpty[({type λ[α]=(α =>: α)})#λ] = new PlusEmpty[({type λ[α]=(α =>: α)})#λ] with ComposePlus { def empty[A] = id }
def foldRightM[G[_], A, B](fa: F[A], z: => B) (f: (A, => B) => G[B]) (implicit M: Monad[G]): G[B] = foldLeft[A, B => G[B]](fa, M.point(_))((b, a) => w => M.bind(f(a, w))(b))(z)
\[\begin{aligned} x & \in \mathbb{Z} \\ \end{aligned} \]
x : Int
\[\begin{aligned} x & \in \mathbb{Z} \\ \end{aligned} \]
x : Int
\[\begin{aligned} x & \in \mathbb{R} \\ \end{aligned} \]
x : Double
val x : Int = 3 val y : Double = 3.0 val f : Artist = new Artist("Frank Zappa")
def add(x: Int, y: Int): Int = x + y
var x = 3 var y: Int = 4 var sum = add(x,y) sum = add(sum, x)
val x = 3 val y: Int = 4 val sum = add(x, y)
val x: Int = { println("eval") 3 } def y: Int = { println("eval") 3 }
scala> val x: Int = {println("eval"); 3} eval x: Int = 3 scala> x res0: Int = 3 scala> x res1: Int = 3
scala> val x: Int = {println("eval"); 3} eval x: Int = 3 scala> x res0: Int = 3 scala> x res1: Int = 3
scala> def y: Int = {println("eval"); 3} y: Int scala> y eval res2: Int = 3 scala> y eval res1: Int = 3
scala> val sqrt = (x : Int) => x * 2 sqrt: Int => Int = <function1> scala> sqrt(2) res9: Int = 4 scala> sqrt res10: Int => Int = <function1>
scala> def sqrt(x: Int) : Int = x * 2 sqrt: (x: Int)Int scala> sqrt(2) res10: Int = 4 scala> def sqrt(x: Int) : Int => Int = { x: Int => x * 2 } sqrt: (x: Int)Int => Int scala> sqrt(2) res11: Int => Int = <function1>
scala> def add(x: Int, y: Int) = x + y scala> add(2, 4) res0: Int = 6 scala> def add(x: Int)(y: Int) = x + y scala> add(2)(4) scala> add(2) { 4 }
scala> def add(x: Int) = (y: Int) => x + y res1: Int => Int = <function1> scala> val t = add(3) res2: Int => Int = <function1> scala> val u = t(3) res3: Int = 6
class QItem
class QItem
val item: QItem = new QItem() val item = new QItem() val item = new QItem
class QItem(val addTime: Time, var expiry: Time, data: Array[Byte])
class QItem(val addTime: Time, var expiry: Time, data: Array[Byte])
val item = new QItem(.....) //val item: QItem = new QItem(.....) scala> item.addTime res0: .... scala> item.expiry res1: .... scala> item.expiry = .... item.expiry: Time = ....
case class QItem(addTime: Time, expiry: Time, data: Array[Byte])
case class QItem(addTime: Time, expiry: Time, data: Array[Byte]) { val xid: Int = 0 final def pack(opcode: Byte): ByteBuffer = pack(opcode, xid) final def pack(opcode: Byte, xid: Int): ByteBuffer = { val buffer = ByteBuffer.allocate(data.length + 21 + (if (xid == 0) 0 else 4)) ... buffer } }
case class QItem(addTime: Time, expiry: Time, data: Array[Byte]) { val xid: Int = 0 def this(addTime: Time, expiry: Time) = this(addTime, expiry, 0) final def pack(opcode: Byte): ByteBuffer = {...} final def pack(opcode: Byte, xid: Int): ByteBuffer = {...} }
object QItem
object QItem { def unpack(data: Array[Byte]): QItem = ... }
val data:Array[Byte] = ... val now: Time = Now val item = QItem.unpack(data) val item = QItem unpack data
object QItem { def unpack(data: Array[Byte]): QItem = ... def +(data: QItem): QItem = ... }
val data:Array[Byte] = ... val now: Time = Now val item: QItem = QItem(data).+(QItem(data)) val item: QItem = QItem(data) + QItem(data)
scala> 1.+(2) res0: Double = 3.0 scala> (1).+(2) res1: Int = 3 scala> 1 + 2 res2: Int = 3 scala> 1 toString res3: String = 1
object QItem { def apply(addTime: Time, expiry: Time, data: Array[Byte]): QItem = new QItem(addTime, expiry, data) def apply(data: Array[Byte]): QItem = { val t: Time = Now new QItem(t, t + 3, data) } }
object QItem { def apply(addTime: Time, expiry: Time, data: Array[Byte]): QItem = new QItem(addTime, expiry, data) def apply(data: Array[Byte]): QItem = { val t: Time = Now new QItem(t, t + 3, data) } }
val data:Array[Byte] = ... val now: Time = Now val item = QItem(now, now + 3, data) val item = QItem(data)
def bubleSort (arr: Array[Int], order: (Int, Int) => Boolean): Array[Int] { ... val o: Boolean = order(a, b) ... }
val arr = Array(3,4,6,7,2,8,1) bubbleSort(arr, (a: Int, b: Int) => a > b) bubbleSort(arr, (a: Int, b: Int) => a < b)
val asc: (Int, Int)=>Boolean = (x: Int, y:Int) => x > y val desc: (Int, Int)=>Boolean = (x: Int, y:Int) => x < y
val asc: (Int, Int)=>Boolean = (x: Int, y:Int) => x > y val desc: (Int, Int)=>Boolean = (x: Int, y:Int) => x < y
val arr = Array(3,4,6,7,2,8,1) bubbleSort(arr, asc) bubbleSort(arr, desc)
val arr = Array(3,4,6,7,2,8,1) bubbleSort(arr, _ > _) bubbleSort(arr, _ < _)
val asc: (Int, Int)=>Boolean = (x: Int, y:Int) => x > y val desc: (Int, Int)=>Boolean = (x: Int, y:Int) => x < y
val asc: (Int, Int)=>Boolean = (x: Int, y:Int) => x > y val asc = new Function2[Int, Int, Boolean] { def apply(x: Int, y: Int): Boolean = x > y }
val desc: (Int, Int)=>Boolean = (x: Int, y:Int) => x < y val desc = new Function2[Int, Int, Boolean] { def apply(x: Int, y: Int): Boolean = x < y }
trait Function0[+R] extends AnyRef
val javaVersion = () => sys.props("java.version") val anonfun0 = new Function0[String] { def apply(): String = sys.props("java.version") }
trait Function1[-T1, +R] extends AnyRef
val succ = (x: Int) => x + 1 val anonfun1 = new Function1[Int, Int] { def apply(x: Int): Int = x + 1 }
trait Function2[-T1, -T2, +R] extends AnyRef
val max = (x: Int, y: Int) => if (x < y) y else x val anonfun2 = new Function2[Int, Int, Int] { def apply(x: Int, y: Int): Int = if (x < y) y else x }
trait Animal case class Dog extends Animal case class Cat extends Animal
object Animal { def apply(type: String) { type match { case "cat" => new Cat() case "dog" => new Dog() case _ => throw new Exception } } }
val animal = Animal("dog")
scala> val x = {println("eval"); 3} eval x: Int = 3 scala> x res0: Int = 3
scala> val x = {println("eval"); 3} eval x: Int = 3 scala> x res0: Int = 3
scala> lazy val x = {println("eval"); 3} x: Int = <lazy> scala> x eval res0: Int = 3
object Connection { val connection: .... }
trait Log { def warning(message: String) def error(message: String) } final class Logger { def log(level: Level, message: String) { /* ... */ } } implicit class LoggerToLogAdapter(logger: Log) extends Log { def warning(message: String) { logger.log(WARNING, message) } def error(message: String) {logger.log(ERROR, message)} } val: Log = new Logger()
class Coffee { val sep = ", " def cost:Double = 1 def ingredients: String = "Coffee" }
trait Milk extends Coffee { abstract override def cost = super.cost + 0.5 abstract override def ingredients = super.ingredients + sep + "Milk" }
trait Whip extends Coffee { abstract override def cost = super.cost + 0.7 abstract override def ingredients = super.ingredients + sep + "Whip" }
trait Sprinkles extends Coffee { abstract override def cost = super.cost + 0.2 abstract override def ingredients = super.ingredients + sep + "Sprinkles" }
val coffeeWithSprinkles: Coffee = new Coffee with Sprinkles val coffeeWithMilk: Coffee = new Coffee with Sprinkles with Milk val coffeeWithMilkAndWhip = new Coffee with Sprinkles with Milk with Whip
val point = (1,2)
type Point = (Int, Int) val point: Point = (1,2)
val point = (1,2)
trait Sound { def play() } class Music extends Sound { def play() { /* ... */ } } object SoundSystem { def getSound: Option[Sound] = if (available) Some(music) else None } for (sound <- SoundSystem.getSound) { sound.play() }
type Strategy = (Int, Int) => Int class Context(computer: Strategy) { def use(a: Int, b: Int) { computer(a, b) } } val add: Strategy = _ + _ val multiply: Strategy = _ * _ new Context(multiply).use(2, 3)
trait Repository { def save(user: User) } trait DatabaseRepository extends Repository { /* ... */ } trait UserService { self: Repository => // requires Repository def create(user: User) { // ... save(user) } } new UserService with DatabaseRepository
val list = 1 :: 2 :: 3 :: Nil
val list = List(1, 2, 3)
val list = head :: tail val list = head :: (head :: (head :: tail))
scala> list.filter(x => x % 2 == 1) res0: List[Int] = List(1,3) scala> list res1: List[Int] = List(1,2,3)
scala> list.filter(x => x % 2 == 1) res0: List[Int] = List(1,3) scala> list res1: List[Int] = List(1,2,3)
def filter(p: (A) ⇒ Boolean): List[A]
def isOdd(x: Int) = x % 2 == 0 val isEven: Int => Boolean = i => i % 2 != 0
def map[B](f: (A) ⇒ B): TraversableOnce[B]
val list = "Aaa" :: "Bbb" :: "Ccc" :: Nil
scala> list.map((s: String) => s.toLowerCase) scala> list.map(s => s.toLowerCase)
scala> list.filter(x => x % 2 == 1) res0: List[Int] = List(1,3) scala> list res1: List[Int] = List(1,2,3)
scala> list.map(_.length) res0: List[Int] = List(3, 3, 3)
case class Person(val age: Int, val first: String, val last: String)
def filterByAge(in: List[Person]) = in .filter(_.age > 30) .sort(_.age < _.age) .map(_.first)
def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): TraversableOnce[B]
scala> list.flatMap(x => x.map(_.toInt)) List[Int] = List(65, 97, 97, 66, 98, 98, 67, 99, 99)
def add(x: Int, y: Int) = x + y def sub(x: Int, y: Int) = x - y
def calculator(op: String)(x: Int, y: Int) = op match { case "+" => add(x, y) case "-" => sub(x, y) case _ => throw new IllegalStateException }
def calculator(op: String)(x: Int, y: Int) = op match { case "+" => add(x, y) case "-" => sub(x, y) case _ => throw new IllegalStateException }
scala> calculator("+")(3,2) res0: Int = 5 calculator("-")(3,2) res1: Int = 1
def f(x: Any) = x match { case i: Int => s"integer $i" case d: Double => s"double $d" case s: String => "string $s" } f(1) f(2.0) f("string")
def fun(xs: List[Int]): Int = { def fun(xs: List[Int], acc: Int): Int = xs match { case y :: ys => fun(ys, acc + y) case Nil => acc } fun(xs, 0) }
def sum(xs: List[Int]): Int = { def sum(xs: List[Int], acc: Int): Int = xs match { case y :: ys => sum(ys, acc + y) case Nil => acc } sum(xs, 0) }
scala> sum(List(1,2,3)) res0: Int = 6
def length[A](list : List[A]) : Int = list match { case _ :: tail => 1 + length(tail) case Nil => 0 }
def listAnalysis(list: List[Any]) = list match { case Nil => "empty" case 'a' :: tail => "starting by 'a'" case (head:Int) :: _ if head > 3 => "starting by an int greater than 3" case (head:Int) :: _ => "starting by an int" case _ => "whatever" }
sealed abstract class Op case class Const(value: Int) extends Op case class Add(left: Op, right: Op) extends Op case class Sub(left: Op, right: Op) extends Op
scala> def eval(op: Op): Int = op match { case Const(x) => x case Add(left, right) => eval(left) + eval(right) case Sub(left, right) => eval(left) - eval(right) } res0: eval: (op: Op) Int
scala> val expr = eval(Sub(Const(5), Add(Const(2), Const(1)))) res1: expr : Int = 2
type Word = String type Count = Int String => Map[Word, Count]
def wordCount(text: String) = Map[Word, Count] = text .split(" ") .map(a => (a, 1)) .groupBy(_._1) .map { a => a._1 -> a._2.map(_._2).sum }
sbt> ~test