5μ£Όμ°¨ (21 ~ 25 Chapter)
Chapter 21 μμμ λ³νκ³Ό μμμ νλΌλ―Έν°
μΌλ°μ μΌλ‘ λ€λ₯Έ μ¬λμ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νκ³ μΆμ κ²½μ°μλ λ³΄ν΅ μλ κ·Έλλ‘ μ¬μ©ν΄μΌ νλ€λ μ μ΄λ€.
μ΄λ₯Ό κ°μ νκΈ° μν΄ νλ‘κ·Έλλ° μΈμ΄λ€μ λ€μν μμλ₯Ό λμ ν΄ μλ€.
- λ£¨λΉ & μ€λͺ°ν ν¬ -> ν¨ν€μ§λ€μ΄ μλ‘ ν΄λμ€λ₯Ό μΆκ°ν μ μμ
- C# -> μ μ λ©μλ (static extendsion method) κ° μμ΄ μ’ λ μ§μμ μΌλ‘ λ³κ²½ν μ μμ
μ€μΉΌλΌμμλ μμμ λ³νμ΄λΌλ ν΄λ²μ μ 곡νλ€.
21.1 μμμ λ³ν
μμμ λ³νμ μ¬μ©νλ©΄ ν νμ μ λ€λ₯Έ νμ μΌλ‘ λ³κ²½νλ λ° νμν λͺ μμ μΈ λ³νμ μ«μλ₯Ό μ€μΌ μ μλ€.
val button = new JButton
button.addActionListener(
new ActionListener {
def actionPerformed(event: ActionEvent) {
println("pressed!")
}
}
)
μ μ½λλ₯Ό μ€μΉΌλ¦¬ μΉνμ μΌλ‘ λ°κΎΌλ€.
button.addActionListener( // νμ
λΆμΌμΉ!
(_: ActionEvent) => println("pressed!")
)
μ μ½λλ λμλμ§ μλλ€.
addActionListener
κ° μνλ κ²μ ActionListener
μ΄κΈ° λλ¬Έμ΄λ€.
μ΄λ λ€μκ³Ό κ°μ΄ μμμ λ³νλ°©λ²μ μ¬μ©νμ¬ μμ±νλ€.
implicit def function2ActionListener(f: ActionEvent => Unit) =
new ActionListener {
def actionPerformed(event: ActionEvent) = f(event)
}
function2ActionListener
κ° implicit
λ‘ νκΈ°ν΄λκΈ° λλ¬Έμ, μ΄λ₯Ό μλ΅ν΄λ μ»΄νμΌλ¬κ° μλμΌλ‘ μΆκ°ν΄μ€λ€.
21.2 μμ κ·μΉ
νμ κ·μΉ: implicitλ‘ νμν μ μλ§ κ²ν λμμ΄λ€.
λ³μ, ν¨μ, κ°μ²΄ μ μμ implicit
νμλ₯Ό λ¬ μ μλ€.
implicit def intToString(x: Int) = x.toString
μ»΄νμΌλ¬λ μμμ μ΄λΌκ³ λͺ μν μ μ μ€μμλ§ λ³ν ν¨μλ₯Ό μ°Ύλλ€.
μ€μ½ν κ·μΉ: μ½μ λ implicit λ³νμ μ€μ½ν λ΄μ λ¨μΌ μλ³μλ‘λ§ μ‘΄μ¬νκ±°λ, λ³νμ κ²°κ³Όλ μλ νμ κ³Ό μ°κ΄μ΄ μμ΄μΌ νλ€.
μμμ λ³νμ λ¨μΌ μλ³μλ‘λ§ μ€μ½ν μμ μ‘΄μ¬ν΄μΌ νλ€.
μ»΄νμΌλ¬λ someVariable.convert
κ°μ ννμ λ³νμ μ½μ
νμ§ μλλ€.
x + y
λ₯Ό someVariable.convert(x) + y
λ‘ νμ₯νμ§ μλλ€.
λ§μ½ μ΄λ₯Ό μν΄μλ someVariable.convert
λ₯Ό λ¨μΌ μλ³μλ‘ κ°λ₯΄ν¬ μ μκ² λ§λ€μ΄μΌ νλ€.
λ¨μΌ μλ³μλ ν κ°μ§ μμΈκ° μλ€.
μ»΄νμΌλ¬λ μ νμ μ΄λ λ°ν κ²°κ³Ό νμ μ λλ° κ°μ²΄μ μλ μμμ μ μλ μ΄ν΄λ³Έλ€.
object Dollar {
implicit def dollarToEuro(x: Dollar): Euro = ...
}
class Dollar { ... }
μ»΄νμΌλ¬λ Dollar
νμ
μ μΈμ€ν΄μ€λ₯Ό λ€λ₯Έ νμ
μΌλ‘ λ³νν νμκ° μμ λλ§λ€ μ°κ΄μ΄ μλ λ³νμ μ°Ύλλ€.
ν λ²μ νλλ§ κ·μΉ: μ€μ§ νλμ μμμ μ μΈλ§ μ¬μ©νλ€.
μ»΄νμΌλ¬λ x + y
λ₯Ό convert1(convert2(x)) + y
λ‘ λ³ννμ§ μλλ€.
κ·Έλ κ² νλ©΄ μλͺ» μμ±ν μ½λλ₯Ό μ»΄νμΌνλ μκ°μ΄ κ·Ήμ μΌλ‘ λμ΄λκ³ νλ‘κ·Έλλ¨Έκ° μμ±ν μ½λμ κ·Έ νλ‘κ·Έλ¨μ΄ μ€μ νλ μΌ μ¬μ΄μ μ°¨μ΄κ° 컀μ§λ€.
λͺ μμ± μ°μ κ·μΉ: μ½λκ° κ·Έ μν κ·Έλλ‘ νμ κ²μ¬λ₯Ό ν΅κ³Όνλ€λ©΄ μμλ₯Ό ν΅ν λ³νμ μλνμ§ μλλ€.
μ»΄νμΌλ¬λ μ΄λ―Έ μ μλνλ μ½λλ₯Ό λ³κ²½νμ§ μλλ€.
μμμ λ³ν μ΄λ¦ λΆμ΄κΈ°
μμμ λ³νμλ μ무 μ΄λ¦μ΄λ λΆμΌ μ μλ€.
μ΄λ¦μ΄ λ¬Έμ κ° λλκ²μ λ€μ λ κ°μ§ λΏμ΄λ€.
- λ©μλ νΈμΆ μ λͺ μμ μΌλ‘ λ³νμ μ¬μ©νκ³ μΆμ κ²½μ°
- νλ‘κ·Έλ¨μ νΉμ μ§μ μμ μ¬μ© κ°λ₯ν μμμ λ³νμ΄ μ΄λ€ κ²μ΄ μλμ§ νμ ν΄μΌ νλ κ²½μ°
object MyConversions {
implicit def stringWrapper(s: String): IndexedSeq[Char] = ...
implicit def intToString(x: Int): String = ...
}
stringWrapper
λ³νμ μ¬μ©νκ³ μΆμ§λ§ intToString
λ λ§κ³ μΆλ€.
import MyConversions.stringWrapper
μ μ½λ μ²λΌ νΉμ μμμ λ³νλ§ μν¬νΈνλ€.
μμκ° μ°μ΄λ λΆλΆ
- κ°μ μ»΄νμΌλ¬κ° μνλ νμ μΌλ‘ λ³νν λ
- μ΄λ€ μ νμ μμ κ°μ²΄λ₯Ό λ³νν λ
- μμμ νλΌλ―Έν°λ₯Ό μ§μ ν λ
21.3 μμ νμ μΌλ‘μ μμμ λ³ν
val i: Int = 3.5
<console>:4: error: type mismatch;
found : Double(3.5)
required: Int
val i: Int = 3.5
^
implicit def doubleToInt(x: Double) = x.toInt
μ΄μ μ΄ μ½λλ λ€μκ³Ό κ°μ΄ λ°λλ€.
val i: Int = doubleToInt(3.5)
scala.Predef
λ λͺ¨λ μ€μΉΌλΌ νλ‘κ·Έλ¨μ μμμ μΌλ‘ μν¬νΈ λλ€.
λ μμ μ νμ μ λ ν° κ²μΌλ‘ λ³ννλ μμμ λ³νλ€μ΄ λ€μ΄μλ€.
implicit def int2double(x: Int): Double = x.toDouble
21.4 νΈμΆ λμ κ°μ²΄ λ³ν
μμμ λ³νμ λ©μλλ₯Ό νΈμΆνλ λμμ΄ λλ κ°μ²΄μΈ μμ κ°μ²΄μλ μ μ©ν μ μλ€.
- μμ κ°μ²΄ λ³νμ ν΅ν΄ μ ν΄λμ€λ₯Ό κΈ°μ‘΄ ν΄λμ€ κ³μΈ΅κ΅¬μ‘°μ 맀λλ½κ² ν΅ν© κ°λ₯
- μΈμ΄ μμμ λλ©μΈμ νΉν μΈμ΄ (DSL) λ₯Ό λ§λλ μΌμ μ§μ
μ νμ κ³Ό κΈ°μ‘΄ νμ ν΅ν©νκΈ°
class Rational(n: Int, d: Int) {
...
def + (that: Rational): Rational = ...
def + (that: Int): Rational = ...
}
val oneHalf = new Rational(1, 2)
oneHalf + oneHalf
oneHalf + 1
// μλ¬
1 + oneHalf
μλμ κ°μ΄ λ³νμ λ§λ€μ΄ λλ©΄ μμ κ°μ²΄λ€μ΄ λλ¨Έμ§ μ²λ¦¬λ₯Ό ν΄μ€λ€.
implicit def intToRational(x: Int) = new Rational(x, 1)
1 + oneHalf
μλ‘μ΄ λ¬Έλ² νλ΄λ΄κΈ°
μ€μΉΌλΌλ μμμ λ³νμ ν΅ν΄ μ λ¬Έλ²μ μΆκ°ν κ² μ²λΌ νλ΄λΌ μ μλ€.
Map(1 -> "one", 2 -> "two", 3 -> "three")
->
λ λ¬Έλ²μ΄ μλ μ€μΉΌλΌ ν리μ λΈμμ μ§μνλ ArrowAssoc
ν΄λμ€μ λ©μλμ΄λ€.
package scala
object Predef {
class ArrowAssoc[A](x: A) {
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] =
new ArrowAssoc(x)
...
}
μμμ ν΄λμ€
μμμ ν΄λμ€λ implicit
ν€μλκ° ν΄λμ€ μ μΈλΆ μμ μλ ν΄λμ€μ΄λ€.
case class Rectangle(width: Int, Height: Int)
implicit class RectangleMaker(width: Int){
def x(height: Int) = Rectangle(width, height)
}
μ μ½λλ₯Ό μΆκ°ν¨μΌλ‘μ¨ μλμ κ°μ΄ λλΉ 3 λμ΄ 4 μ μ¬κ°ν κ°μ²΄λ₯Ό μ½κ² λ§λ€μ μλ€.
val myRectangle = 3 x 4
μμμ ν΄λμ€λ μΌμ΄μ€ ν΄λμ€ μΌ μ μμΌλ©° μμμ ν΄λμ€μ μμ±μμλ νλΌλ―Έν°κ° 1κ°λ§ μμ΄μΌ νλ€.
21.5 μμμ νλΌλ―Έν°
object Greeter {
def greet(name: String)(
// νλΌλ―Έν° λͺ©λ‘μ implicit λ₯Ό λͺ
μ
implicit prompt: PreferredPrompt,
drink: PreferredDrink
) {
println("Welcome, "+ name +". The system is ready.")
print("But while you work, ")
println("why not enjoy a cup of "+ drink.preference +"?")
println(prompt.preference)
}
}
object JoesPrefs {
// μμμ νλΌλ―Έν°μ implicit λ₯Ό λͺ
μ
implicit val prompt = new PreferredPrompt("Yes, master> ")
implicit val drink = new PreferredDrink("tea")
}
implicit
ν€μλλ κ°λ³μ μΈ νλΌλ―Έν°κ° μλκ³ μ 체 νλΌλ―Έν° λͺ©λ‘μ λ²μλ‘ νλ€.
μμ νλΌλ―Έν°μ λν μ€νμΌ κ·μΉ
μμμ νλΌλ―Έν° νμ μ μΌλ°μ μ΄μ§ μλ νΉλ³ν μ΄λ¦μ μ¬μ©νλ€.
def maxListPoorStyle[T](elements: List[T])(implicit orderer: (T, T) => Boolean): T
λͺ μμ μΌλ‘ νμ μ λν μ΄λ ν μ 보λ μ 곡νμ§ μμΌλ©° νν νμ μ΄κΈ° λλ¬Έμ μ»΄νμΌλ¬μμ μ€μλ‘ μ΄μν κ°μ μμμ νλΌλ―Έν°λ₯Ό λ£μμ μλ€.
μμμ νλΌλ―Έν° νμ μ μνμ μλ € μ€ μ μλ μ΅μν νλμ μ΄λ¦μ μ¬μ©ν΄μΌ νλ€.
21.6 λ§₯λ½ λ°μ΄λ
def maxListOrdering[T](elements: List[T])(implicit ordering: Ordering[T]): T =
elements match {
case List() =>
throw new IllegalArgumentException("empty list!")
case List(x) => x
case x :: rest =>
// ordering μ μμμ μΌλ‘ μ¬μ©
val maxRest = maxListOrdering(rest)
// λͺ
μμ μΌλ‘ ordering μ μ¬μ©
if (ordering.gt(x, maxRest)) x
else maxRest
}
μμμ λ³νμ μμ λ λ°©λ²μ νμ€ λΌμ΄λΈλ¬λ¦¬μ μλ μλ λ©μλλ₯Ό μ¬μ©νλ©΄ ν΄λΉ κ°μ²΄λ₯Ό νΈμΆνμ¬ μ¦μ λλ €μ€λ€.
def implicitly[T](implicit t: T) = t
λ§₯λ½ λ°μ΄λ (context bound) λ νμ μ μ μλ₯Ό λ³κ²½νμ§ μκ³ λ κ·Έκ²μ λμ κ°λ₯νκ² μ§μνλ€.
def maxListOrdering[T: Ordering](elements: List[T]): T =
elements match {
case List() =>
throw new IllegalArgumentException("empty list!")
case List(x) => x
case x :: rest =>
val maxRest = maxListOrdering(rest)
if (implicitly[Ordering[T]].gt(x, maxRest)) x
else maxRest
}
21.7 μ¬λ¬ λ³νμ μ¬μ©νλ κ²½μ°
μ€μΉΌλΌλ μ λμ μΌλ‘ λ ꡬ체μ μ΄λΌλ©΄ μ»΄νμΌλ¬λ λ ꡬ체μ μΈκ²μ μ ν νλ€.
- μ μμ μΈμ νμ μ΄ νμμ μλΈνμ μ΄λ€.
- λ λ³ν λͺ¨λ λ©μλμΈλ°, μ μλ₯Ό λλ¬μΌ ν΄λμ€κ° νμλ₯Ό λλ¬μΌ ν΄λμ€λ₯Ό νμ₯νλ€.
val cba = "abc".reverse
"abc"
λ 컬λ μ μΌλ‘ λ³νreverse
λ 컬λ μ μ λ°νcba
λ 컬λ μ μ λ°ν
// false
"abc" == "abc".reverse.reverse
21.8 μμ λλ²κΉ
μ»΄νμΌλ¬κ° μ°Ύμ§ λͺ»νλ κ²½μ° λ³νμ λͺ μμ μΌλ‘ μ¨λ³Έλ€.
μ€λ₯μ μμΈ μΆμ μ΄ μ½λ€.
val chars: List[Char] = "xyz"
val chars: List[Char] = wrapString("xyz")
scala -Xprint:typer
λ₯Ό μ¬μ©νλ©° λ΄λΆμμ νμ
κ²μ¬ μ΄ν μμ€μ½λλ₯Ό μΆλ ₯νκ² νλ€.
21.9 κ²°λ‘
μ€μΉΌλΌμμ μμλ κ°λ ₯νλ©°, μ½λλ₯Ό μμΆν΄μ£Όλ κΈ°λ₯μ΄λ€.
μμλ₯Ό λ무 μμ£Ό μ¬μ©νλ©΄ μ½λλ₯Ό μ΄ν΄νκΈ° μ΄λ €μμ§ μ μλ€.
Chapter 22 리μ€νΈ ꡬν
μ€μΉΌλΌμμ κ°μ₯ λ리 μ¬μ©λλ ꡬ쑰νλ λ°μ΄ν° νμ μ΄λ€.
21.1 List ν΄λμ€ κ°κ΄
Nil κ°μ²΄
Nil κ°μ²΄λ λΉ λ¦¬μ€νΈλ₯Ό μ μνλ€.
Nil κ°μ²΄λ List[Noting] μ μμνλ€.
:: ν΄λμ€
final case class ::[T](hd: T, tl: List[T]) extends List[T] {
def head = hd
def tail = tl
override def isEmpty: Boolean = false
}
μΆκ° λ©μλ
def length: Int =
if (isEnpty) 0 else 1 + tail.length
def drop(n: Int): List[A] =
if (isEmpty) Nil
else if (n <= 0) this
else tail.drop(n - 1)
def map[B](f: A => B): List[B] =
if (isEmpty) Nil
else f(head) :: tail.map(f)
리μ€νΈ ꡬμ±
리μ€νΈ κ΅¬μ± λ©μλμΈ ::
μ :::
λ κ°κ°μ΄ μ½λ‘ (π μΌλ‘ λλκΈ° λλ¬Έμ μ€λ₯Έμͺ½ νΌμ°μ°μμ λ°μΈλ© λλ€.
x :: xs
κ° x.::(xs)
κ° μλκ³ xs.::(x)
νΈμΆκ³Ό κ°λ€.
::
λ©μλλ μμκ°μ λ°μμ μ 리μ€νΈλ₯Ό λ§λ€μ΄ λ΄μΌ νλ€.
abstract class Fruit
class Apple extends Fruit
class Orange extends Fruit
scala> val apples = new Apple :: Nil
apples: List[Apple] = List(Apple@585fa9)
scala> val fruits = new Orange :: apples
fruits: List[Fruit] = List(Orange@cd6798, Apple@585fa9)
리μ€νΈμ μ μκ° κ³΅λ³μ μ΄κΈ° λλ¬Έμ λ©μλ νλΌλ―Έν°λ₯Ό λ°κ³΅λ³μΌλ‘ ν¨μΌλ‘μ¨ λ μ μ°νκ³ μμ μ μΌλ‘ μ¬μ© κ°λ₯νκ² λ§λ€μ΄ μ€λ€.
def ::[U >: T](x: U): List[U] = new scala.::(x, this)
22.2 ListBuffer ν΄λμ€
리μ€νΈμ λν μ νμ μΈ μ κ·Ό ν¨ν΄μ μ¬κ·μ μ΄λ€.
:::
μ²λ¦¬λ 첫 μΈμμ κΈΈμ΄μ λΉλ‘νλ μκ°μ κ°κΈ° λλ¬Έμ λΉν¨μ¨μ μ΄λ€.
리μ€νΈ λ²νΌλ₯Ό μ¬μ©νλ©΄ μμλ₯Ό μΆμ ν μ μλ€.
var result = List[Int]()
for (x <- xs) result = result ::: List(x + 1)
result
import scala.collection.mutable.ListBuffer
val buf = new ListBuffer[Int]
for (x <- xs) buf += x + 1
buf.toList
22.3 μ€μ List ν΄λμ€
λΉ κΌ¬λ¦¬ μ¬κ· ꡬνκ³Ό κ°μ μ€ν μ€λ²νλ‘μ° λ¬Έμ κ° μκΈΈ κ²½μ°μλ μ€μ λ‘ κ΅¬ννλ List μμλ μ¬κ·λ₯Ό ννΌνκ³ λ¦¬μ€νΈ λ²νΌμ 루νλ₯Ό μννλ λ°©μμ μ ννλ€.
final override def map[B](f: A => B): List[B] = {
if (this eq Nil) Nil else {
val h = new ::[B](f(head), Nil)
var t: :: [B] = h
var rest = tail
while (rest ne Nil) {
val nx = new ::(f(rest.head), Nil)
t.next = nx
rest = rest.tail
}
h
}
}
package scala.collection.immutable
class ListBuffer[A] extends Buffer[A] {
private var first: List[A] = Nil
private var list0: ::[A] = null
private var aliased: Boolean = false
...
}
ListBuffer μ νΉμ±μ κ²°μ νλ μΈκ°μ§ λΉκ³΅κ° νλλ₯Ό λ³Ό μ μλ€.
- first: λ²νΌμ μ μ₯λ λͺ¨λ μμμ 리μ€νΈλ₯Ό κ°λ₯΄ν¨λ€.
- last0: 리μ€νΈμ λ§μ§λ§
::
μ μ κ°λ¦¬ν¨λ€. - aliased:
toList
λ₯Ό μ¬μ©ν΄ λ²νΌλ₯Ό 리μ€νΈλ‘ λ°κΎΌ μ μ΄ μλμ§ νμνλ€.
22.4 μΈλΆμμ λ³Ό λλ ν¨μν
리μ€νΈκ° μΈλΆμμλ μμ ν ν¨μμ μ΄μ§λ§, λ΄λΆμμλ 리μ€νΈ λ²νΌλ₯Ό μ¬μ©ν΄ λͺ λ ΉνμΌλ‘ λμ΄ μλ€.
μ΄λ μμνμ§ μλ μ°μ°μ ν¨κ³Όκ° λ―ΈμΉλ λ²μλ₯Ό μ£ΌμκΉκ² μ νν¨μΌλ‘μ¨ ν¨μμ μμμ±μ ν¨μ¨μ μΌλ‘ λ¬μ±νλ €λ κ²μ΄λ€.
val ys = 1 :: xs
val zs = 2 :: xs
ys
μ zs
λ 꼬리λ₯Ό 곡μ νλ€.
ν¨μ¨μ μν΄μ νμμ μ΄λ©°, xs μ μλ‘μ΄ μμλ₯Ό μΆκ°ν λλ§λ€ μ 체λ₯Ό 볡μ¬ν΄μΌ νλ€λ©΄ ν¨μ¬ λ릴κ²μ΄λ€.
// μ€μΉΌλΌμμλ λΆκ°λ₯
ys.drop(2).tail = Nil
λΆμ ν¨κ³Όλ‘ ys
μ zs
리μ€νΈλ μ€μ΄λ€ μ μλ€.
λ³΄ν΅ ::
λ λΆν μ 볡 (divide-and-conquer) μ€νμΌμ μ¬κ·μ μκ³ λ¦¬μ¦μ μ λ§μ λ¨μ΄μ§λ€.
리μ€νΈ λ²νΌλ μ’ λ μ ν΅μ μΈ λ£¨ν μ€νμΌμμ λ§μ΄ μ¬μ©νλ€.
22.5 κ²°λ‘
리μ€νΈλ μ€μΉΌλΌμμ κ°μ₯ λ§μ΄ μ¬μ©νλ λ°μ΄ν° κ΅¬μ‘°μ€ νλμ΄λ©°, μΈλ°νκ³ κ΅¬νλμ΄ μλ€.
Chapter 23 for ννμ λ€μ보기
case class Person(
name: String,
isMale: Boolean,
children: Person*
)
val lara = Person("Lara", false)
val bob = Person("Bob", true)
val julie = Person("Julie", false, lara, bob)
val persons = List(lara, bob, julie)
λͺ¨λ μλ§μ μμμ μμ μ°Ύκ³ μΆλ€.
persons
filter (p => !p.isMale)
flatMap (p => (p.children map (c => (p.name, c.name))))
persons
withFilter (p => !p.isMale)
flatMap (p => (p.children map (c => (p.name, c.name))))
for (
p <- persons
if !p.isMale
c <- p.children
) yield (p.name, c.name)
μ΄ μλ€μ κ²°κ³Όλ μμ ν κ°λ€.
μ€μΉΌλΌ μ»΄νμΌλ¬λ λ λ²μ§Έ μ§μλ₯Ό 첫 λ²μ§Έ κ²μΌλ‘ λ³ννλ€.
23.1 for ννμ
μΌλ°μ μΈ for ννμμ λ€μκ³Ό κ°λ€.
for ( seq ) yield expr
μ¬κΈ°μ seq
λ μ λλ μ΄ν° (generator), μ μ (difinition), νν° (filter) λ₯Ό λμ΄νκ²μ΄λ€.
for {
p <- persons // μ λλ μ΄ν°
n = p.name // μ μ
if (n startWith "To") // νν°
}
μ λλ μ΄ν°μ ννλ λ€μκ³Ό κ°λ€.
pat <- expr
expr
μ 리μ€νΈλ₯Ό λ°ννλ€.
μ μμ ννλ λ€μκ³Ό κ°λ€.
pat = expr
pat
ν¨ν΄μ expr
μ κ°μ λ°μΈλ©νλ€. (val
μ μ κ°μ μνμ νλ€.)
νν°μ ννλ λ€μκ³Ό κ°λ€.
if expr
μ¬κΈ°μ expr
μ Boolean μ κ°μ΄λ€. νν°λ expr
μ΄ false
νλ κ°μ μ΄ν°λ μ΄μ
μμ μ μΈνλλ‘ λ§λ λ€.
23.2 n μ¬μ λ¬Έμ
μ± μμ μ½λ λ° μ€λͺ μ°Έκ³
23.3 for μμΌλ‘ μ§μνκΈ°
case class Book(title: String, authors: String*)
val books: List[Book] =
List(
Book(
"Structure and Interpretation of Computer Programs",
"Abelson, Harold", "Sussman, Gerald J."
),
Book(
"Principles of Compiler Design",
"Aho, Alfred", "Ullman, Jeffrey"
),
Book(
"Programming in Modula-2",
"Wirth, Niklaus"
),
Book(
"Elements of ML Programming",
"Ullman, Jeffrey"
),
Book(
"The Java Language Specification", "Gosling, James",
"Joy, Bill", "Steele, Guy", "Bracha, Gilad"
)
)
μμ¬μ μ±μ΄ GoslingμΈ λͺ¨λ μ± μ μ λͺ©μ μ°Ύλλ€.
for (
b <- books
a <- b.authors
if a startsWith "Gosling"
) yield b.title
μ λͺ©μ "Program" μ΄λΌλ λ¬Έμμ΄μ΄ λ€μ΄κ° λͺ¨λ μ± μ μ λͺ©μ μ°Ύλλ€.
for (
b <- books
if (b.title indexOf "Program") >= 0
) yield b.title
μ΅μν λ κΆ μ΄μμ μ± μ μ΄ μκ°λ₯Ό λͺ¨λ μ°Ύλλ€.
for (
b1 <- books
b2 <- books
if b1 != b2
a1 <- b1.authors
a2 <- b2.authors
if a1 == a2
) yield a1
23.4 for ννμ λ°ν
μ λλ μ΄ν°κ° νλλ°μ μλ for ννμμ λ³ν
for ( x <- expr1 ) yield expr2
μ μ½λλ μλμ κ°μ΄ λ³ν
expr1. map( x => expr2 )
μ ν°λ μ΄ν°λ‘ μμνκ³ νν°κ° νλ μλ for ννμμ λ³ν
for (
x <- expr1
if expr2
) yield expr3
μ μ½λλ μλμ κ°μ΄ λ³ν
for (x <- expr1 withFilter (x => expr2 )) yield expr3
for ννμμ λ³ν
expr1 withFilter ( x=>expr2 ) map ( x => expr3 )
μ λλ μ΄ν° 2κ°λ‘ μμνλ for ννμμ λ³ν
for (x <- expr1 ; y <- expr2; seq) yield expr3
μ μ½λλ μλμ κ°μ΄ λ³ν
expr1.flatMap(x => for (y <- expr2; seq) yield expr3
μ λλ μ΄ν°μ μλ ν¨ν΄μ λ³ν
for ((x1, ..., xn) <- expr1) yield expr2
μ μ½λλ μλμ κ°μ΄ λ³ν
expr1.map {
case (x1, ... , xn) => expr2
}
μ μ λ³ν
for ( x <- expr1; y = expr2; seq) yield expr3
μ μ½λλ μλμ κ°μ΄ λ³ν
for ((x, y) <- for (x <- expr1) yield (x, expr2); seq) yield expr3
for 루ν λ³ν
for (x <- expr1) body
μ μ½λλ μλμ κ°μ΄ λ³ν
expr1 foreach (x => body)
23.5 μλ°©ν₯ μ μ©
λͺ¨λ for ννμμ map
, flatMap
, filter
κ³ μ°¨ ν¨μ νΈμΆλ‘ λ³νν μ μλ€
νμ§λ§ κ·Έ λ°λλ‘λ κ°λ₯νλ€.
object Demo {
def map[A, B](xs: List[A], f: A => B): List[B] =
for (x <- xs) yield f(x)
def flatMap[A, B](xs: List[A], f: A => List[B]): List[B] =
for (x <- xs; y <- f(x)) yield y
def filter[A](xs: List[A], p: A => Boolean): List[A] =
for (x <- xs if p(x)) yield x
}
23.6 for μΌλ°ν
for ννμμμ λ³νμ μ€μ§ map
, flatMap
, filter
λ©μλμλ§ μμ‘΄νλ€.
λ°λΌμ for νκΈ°λ²μ λ€μν λ°μ΄ν° νμ μ μ μ©ν μ μλ€.
리μ€νΈμ λ°°μ΄μλ for loop
λ μ¬μ©μ΄ κ°λ₯νλ€.
for ννμμ μλ²½ν μ§μμ μν μ νμ μΈ μ€μ
abstract class C[A] {
def map[B](f: A => B): C[B]
def flatMap[B](f: A => C[B]): C[B]
def withFilter(p: A => Boolean): C[A]
def foreach(b: A => Unit): Unit
}
23.7 κ²°λ‘
for ννμμ λ΄λΆλ₯Ό μ΄ν΄λ³΄μλ€.
for ννμμ μ§μνλλ‘ κ΅¬ννλ λ°©λ²μ μ΄ν΄λ³΄μλ€.
Chapter 24 컬λ μ μμΈν λ€μ¬λ€λ³΄κΈ°
μ± μ°Έκ³