16장 working with lists - codeport/scala GitHub Wiki

16.1 List literals

daclouds

List는 array와 유사하지만 중요한 두 가지 다른 점이 있다.

  • List
    • immutable, recursive structure
  • Array
    • mutable, flat

16.2 The List type

daclouds

  • Like arrays, lists are homogeneous: list의 요소는 모두 같은 타입이다.

  • scala에서 list type은 covariant 이다.

    • S가 T의 subtype이라면, List[S]는 List[T]의 subtype이다.

      예를들면, List[String]은 List[Object]의 subtype이다.

  • empty list의 타입은 List[Nothing]임을 기억하자.

    • Nothing은 Scala's class hierachy의 bottom type이다. (Scala의 다른 모든 타입의 subtype이다.)
    • 왜냐하면 list는 covariant이기 때문에 List[Nothing]은 List[T]의 subtype이고,
      empty list object는 List[T]에 들어갈 수 있는 모든 list 타입의 객체라고 볼 수 있다.
      그렇기 때문에 다음과 같은 코드도 허용된다.
    // List() is also of type List[String]!
    val xs: List[String] = List()

16.3 Constructing lists

###zeide

  • 모든 list는 Nil과 ::(cons)로 생성된다.
  • Nil은 empty list를 말한다.
  • ::(cons)는 list의 확장을 말한다.
    scala>  val fruitList = "apple" :: "orange" :: "grape" :: "banana" :: Nil
    fruitList: List[java.lang.String] = List(apple, orange, grape, banana)

    scala> "watermelon" :: fruitList
    res12: List[java.lang.String] = List(watermelon, apple, orange, grape, banana)

16.4 Basic operations on lists

###zeide

  • list의 기본 동작은 다음 세가지로 볼 수 있다.
    • head : list의 첫번째 엘리먼트 반환
    • tail : 첫번째 엘리먼트를 제외한 요소의 리스트를 반환
    • isEmpty : list가 비어있으면 true를 반환
  • List 클래스에 메소드로 정의되어 있다.

16.5 List patterns

###kingori

  • 패턴 매칭에 사용하는 List pattern
    • List(a,b,c) : 정확한 element의 개수를 알고 있을 때
    • a :: b :: rest : element 개수가 2 이상일 때
    • 참고. :: 와 같은 infix method가 pattern에 사용될 경우, ::(op1, op2) 의 constructor pattern으로 해석함.
      • :: 의 경우엔 scala.:: class가 해당됨

16.6 First-order methods on class List

###kingori

  • first-order method: 어떤 function도 인자로 받지 않는 메서드
  • 이번 절에선 몇 가지 유용한 메서드를 설명함~
    • ::: : list 끼리 merge. cf) :: 는 list에 element 추가
    • length : 리스트의 길이. length는 상대적으로 비싼 operation이니 막 쓰지 말 것.
    • init: 마지막 항목만 뺀 리스트, 'last': 마지막 항목. cf) head: 처음 항목, tail: 처음 항목만 뺀 리스트
      • empty list에선 exception 발생
      • O(n) operation. 따라서 가급적 head / tail 구조를 지향할 것.
    • reverse: 순서 뒤집기.
    • drop : 앞 항목들 버리기, take : 앞 항목들 취하기, splitAt : 특정 위치에서 분리하기 xs spliatAt n 의 결과는 (xs take n, xs drop n)과 같음
    • apply : 특정 위치의 항목 취하기. xs apply 2 == xs(2)
    • indices : 유효한 index의 range 를 반환
    • flatten : list of list 를 list로.
    • zip : 두 list를 tuple로 묵은 list로 반홤. 매칭되지 못한 element 는 버림. zipWithIndex : index와 함께 zip함. xs.indeces zip xs 와 동일.
    • unzip : tuple 의 list를 두 개의 list로 반환.
    • toString : list를 string으로 표현. mkString : prefix, separator, postfix 를 지정할 수 있음. 결과를 StringBuffer에 집어넣는 addString도 있음.
    • toArray : List를 Array로, copyToArray : List의 내용을 Array의 특정 위치 이후에 집어넣기, iterator : iterator 얻기.

16.7 Higher-order methods on class List

###kingori

  • higher order function : 다른 function을 인자로 취하는 function
  • map 틱한 메서드
    • map : List의 각 element에 op를 실행한 List를 반환
    • flatMap : map 한 결과로 만들어진 List of List를 List로 flatten 함
    • foreach : procedure를 받고, 결과도 Unit.
  • filtering
    • filter : T => Boolean function 을 받아 결과가 true인 항목만을 포함한 list를 반환
      • partition: T => Boolean function 을 받아 결과가 true인 항목의 list와 false인 항목의 list의 tuple을 반환함.
    • find : 조건을 만족하는 첫 번째 element를 반환. 반환 타입은 Option.
    • takeWhile , dropWhile : 조건을 만족하는 동안 취함, 조건을 만족하는 동안 버림
      • span : takeWhiledropWhile 의 tuple을 반환
    • forall : 모든 항목이 조건을 만족하는지, exists : 조건을 만족하는 항목이 있는지 반환 (Boolean)
  • folding
    • /: : fold left. List의 왼쪽 항목부터 차례로 진행. (z /: xs ) (op) 의 형태를 취함.
      • z: 초기값, xs: List, op: binary operation
(z /: List(a,b,c))(op) == op(op(op(z,a),b),c)
  • :\ : fold right. List의 오른쪽 항목부터 차례로 진행. (xs :\ z) (op) 의 형태를 취함.
  • 동일한 작업이라면 fold right가 효율적이다.
  • sortWith : 소팅. 정렬을 위한 function 을 인자로 받음.

16.8 Methods of the List object

###kingori

굳이 정리할 필요가? 그냥 scaladoc을 봐도 될 듯.

16.9 Processing multiple lists together

###kingori

zip, map 등을 사용하면 여러 복잡한 일을 처리할 수 있다~

16.10 Understanding Scala’s type inference algorithm

###kingori

내용은 길지만 우리가 알아야 할 것: non-functional 인자와 function 인자를 함께 받는 다형성 메서드를 설계할 경우, 가급적 function 인자를 뒤에 둘 것. 그래야 non-functional 인자로 부터 타입 추론을 미리 수행하여 function 인자를 축약된 형태로 사용할 수 있다.