Scala
기초
(4)
Scala 보편적인Collection
컬렉션 프레임워크는 배열, 리스트, 맵, 집합, 트리와 같이 주어진 타입을 가지는 하나 또는 그 이상의 값을
수집하는 데이터 구조를 제공한다.
스칼라는 JVM 언어이므로 스칼라 코드에서 자바 컬렉션 라이브러리 전체에 접근 하고 사용할 수 있다. 물론,
그렇게 한다면 스칼라만이 가지고 있는 컬렉션의 고차 연산이 주는 영광을 놓치게 된다.
스칼라도 자바와 마찬가지로 고성능의, 객체지향적인, 타입-매개변수화된 컬렉션 프레임워크를 가지고 있다.
그러나 스칼라의 컬렉션은 map, filter, reduce와 같이 짧고 표현력이 있는 표현식으로 데이터를 관리하고
처리하는 고차 연산도 가지고 있다. 또한, 가변적인 컬렉션 타입 계층구조와 불변의 컬렉션 타입 계층구조를
별개로 가지고 있어서(안정성을 위한) 불변의 데이터와 (필요하다면) 가변적인 데이터 사이의 전환을 쉽게
만들어준다.
Scala 보편적인Collection
리스트
리스트는 이것을 함수로 호출함으로써 생성할 수 있다. 호출 사이에 그 리스트에 포함될 내용을 쉼표로 구분된
매개변수 형태로 전달한다.
Lisp 스타일의 head()와 tail() 메소드를 사용하여 리스트의 첫
번째 요소와 나머지 요소에 각각 접근해보자.
직접 단일 요소에 접근하려면, 리스트를 함수로 호출하고 그
요소를 가리키는 0부터 시작하는 인덱스를 그 함수에 전달하면
된다.
Scala 보편적인Collection
for 루프로 돌려보자.
리스트
Scala 보편적인Collection
- foreach() 는 함수 (정확하게는 프로시저)를 취하고, 그 함수를
리스트의 모든 항목으로 호출한다.
- map()은 단일 리스트 요소를 다른 값이나 타입으로 전환하는
함수를 취한다.
- reduce()는 두 리스트 요소를 단일 항목으로 결합하는 함수를
취한다.
리스트
foreach(), map(), reduce()를 이용한 예제.
각 함수는 리스트를 반복하고, 전환하며, 리스트를 단일 항목으로 축소한다. 각 메소드에는 함수 리터럴이
전달되는데, 이 함수 리터럴에는 괄호로 묶인 입력 매개변수와 함께 본문이 포함되어 있다.
Scala 보편적인Collection
Set
set은 유일한 요소들로 이루어진 순서가 없는 불변의 컬렉션이지만, List와 유사하게 동작한다.
Scala 보편적인Collection
Map
Map은 불변의 키-값 저장소로, 다른 언어에서는 해시맵(hashmap), 딕셔너리(dictionary) 또는 연관 배열
(associative array)로 알려져 있다. Map에 주어진 유일한 키로 저장된 값을 그 키를 이용하여 추출할 수 있다. 키와
값은 타입-매개변수화되어 여러분은 정수를 문자열에 매핑하는 것처럼 쉽게 문자열을 정수에 매핑할 수 있다.
Map은 생성할 때 키-값 쌍을 튜플로 기술하면 된다. 키와 값 튜플을 기술하기 위해 관계 연산자(->)를 사용 할 수
있다.
Scala 보편적인Collection
리스트에는 무엇이 있는가?
List는 불변의 재귀적인 데이터 구조이므로 리스트의 각 요소는 자신만의 헤드와 점진적으로 더 짧아지는 테일을
가진다. 이를 사용하여 헤드로 시작하여 잇따른 tail들이 지나가는 길을 만들면서 여러분만의 List 반복자(iterator)를
만들 수 있다.
리스트에서 null로 표현될 수 있는 Nil은 근본적으로 List[Nothing]의 싱글턴 인스턴스다. Nothing 타입의 리스트는
따라서 다른 모든 타입의 리스트와 호환됨, 그들의 종점으로 안전하게 사용될 수 있다.
Scala 보편적인Collection
생성 연산자
리스트를 생성하는 다른 방법으로는 이전 절에서 설명한 Nil과의 관계를 이용하는 것이다.
Lisp를 인정하는 또 다른 의미로, 스칼라는 리스트를 만들기 위해 생성(cons, construct의 축양형)연산자의 사용을
지원한다. Nil을 기반으로 항목들을 결합하기 위해 오른쪽 결합형(right-associative) 생성 연산자 ::를 상용하여
전형적인 List(...) 리스트를 만들 수 있다.
Scala 보편적인Collection
리스트의 산술연산
아래 링크 참조.
http://www.scala-lang.org/api/2.7.3/scala/List.html
위의 표에서 고차 함수를 발견했는가? 아래 스칼라 REPL에서 실행된 고차 연산 세가지 예제, fitler, partition,
sortBy가 있다.
Scala 보편적인Collection
리스트의 산술연산
sortBy 메소드는 리스트 항목들의 순서를 정렬하기 위해 사용할 값을 반환하는 함수를 취하는 반면, filter와 partition
메소드는 조건자 함수를 취한다. 조건자 함수 (predicate function)는 하나의 입력값을 받아서 참 또는 거짓을
반환한다.
이 산술 연산자 메소드에서 중요한 점은 ::, drop, take가 리스트의 앞에서 동작하고, 따라서 성능상의 불이익이
없다는 것이다. List는 연결 리스트이기 때문에 그 앞에 항목들을 추가하거나, 그 앞의 항목들을 제거하는 것은
리스트 전체를 순회할 필요가 없다. 리스트가 짧다면 리스트 순회는 사소한 일이겠지만, 수천, 수백만의 항목들을
가진 리스트라면 리스트를 순회해야 하는 연산은 큰일이 될 수 있다.
그렇다고 해도 이러한 연산들은 리스트의 끝에서 동작하는, 따라서 리스트 전체 순회가 필요한 동반 연산(corollary
operation)들을 가지고 있다. 대규모 리스트로 작업하지 않는 한 메모리 활용을 고려할 필요는 없지만, 일반적으로
리스트의 끝이 아니라 앞에서 연산하는 것이 가장 좋다.
Scala 보편적인Collection
리스트 맵핑
Map 메소드는 함수를 취하여 그 함수를 리스트의 모든 요소들에 적용하고, 그 결과를 새로운 리스트에 수집한다.
일반적으로 집합 이론과 수학 분야에서는 매핑한다(map)는 것은 한 집합의 각 요소와 다른 집합의 각 요소 사이에
연관성을 만드는 것이다.
collect : 각 요소를 부분 함수를 사용하여 변환하고, 해당 함수를 적용할 수 있는 요소를 유지함.
flatMap : 주어진 함수를 이용하여 각 요소를 변환하고, 그 결과 리스트를 이 리스트에 평면화(flatten)함.
map : 주어진 함수를 이용하여 각 요소를 변환함.
Scala 보편적인Collection
리스트 축소하기
리스트 축소는 컬렉션으로 작업하는 데 있어 가장 보편적인 연산이다/ 등급 리스트를 합산하거나 여러 성능 테스트
결과의 평균 시간을 계산해야 하는가? 만일 컬렉션이 특정 요소를 포함하는지 검사하고 싶거나, 조건자 함수가
리스트의 모든 요소에 대해 '참'을 반환할 것인지를 알고 싶다면? 이들은 리스트를 단일 값으로 축소하는 로직을
사용하기 때문에 모두 리스트 축소 연산이다.
스칼라의 컬렉션은 수학적 축소 연산(예: 리스트의 합계 구하기)과 부울 축소 연산(예: 리스트가 주어진 요소를
포함하는 여부 확인하기)을 지원한다.
max : 리스트의 최댓값 구하기.
min : 리스트의 최솟값 구하기.
product : 리스트의 숫자들을 곱하기
sum : 리스트의 숫자들을 합산하기
Scala 보편적인Collection
리스트 축소하기
contains : 리스트가 이 요소를 포함하고 있는지를 검사함.
endWith : 리스트가 주어진 리스트로 끝나는지를 검사함.
exists : 리스트에서 최소 하나의 요소에 대해 조건자가 성립하는지를 검사함.
forall : 리스트의 모든 요소에 대해 조건자가 성립하는지를 검사함.
startsWith : 리스트가 주어진 리스트로 시작하는지를 테스트 함.
Scala 보편적인Collection
리스트 축소하기
리스트를 입력 함수 기반으로 축소하는 고차 함수를 속칭 리스트-접기(list-folding)연산이라 하는데, 리스트를
축소하는 함수는 접기(fold)로 더 잘 알려져 있기 때문이다.
Scala 보편적인Collection
컬렉션 전환하기
스칼라에서는 타입 간 전환이 쉬워서 하나의 타입으로 설렉션을 생성하여 다른 타입으로 끝낼 수 있다.
mkString : 주어진 구분자를 사용하여 컬렉션을 String으로 만듬
ex ) List(24, 99, 104).mkString(", ")
toBuffer : 불변의 컬렉션을 가변적인 컬렉션으로 전환
ex ) list('f', 't').toBuffer
toList : 컬렉션을 List로 전환
ex ) Map("a" -> 1, "b" -> 2).toList
toMap : 두 요소(길이)로 구성된 튜플의 컬렉션을 Map으로 전환
ex) Set(1 -> true, 3 -> true).toMap
toSet : 컬렉션을 Set으로 전환
ex) List(2, 5, 5, 3, 2).toSet
toString : 컬렉션을 String으로 컬렉션의 타입을 포함하여 만듦.
ex ) List(2, 5, 5, 3, 2).toString
Scala 보편적인Collection
자바와 스칼라 컬렉션 호환성
자바와 스칼라 상호작용의 일부는 자바 컬렉션과 스칼라 컬렉션 간 전환하는 것인데, 이 두 컬렉션 타입은
기본적으로 호환되지 않는다.
import 명령어는 JavaConverters와 그 메소드를 현재의 네임스페이스에 추가한다.
asJava : 스칼라와 컬렉션을 그에 대응하는 자바 컬렉션으로 전환함.
ex) List(12, 29).asJava
asScala : 이 자바컬렉션을 그에 대응하는 스칼라 컬렉션으로 전환함.
ex) new java.util.ArrayList(5).asScala
Scala 보편적인Collection
컬렉션으로 패턴 매칭하기
패턴 가드에서 와일드 카드('_')로 컬렉션의 일부 또는 모든 요소에 값을 바인딩 할 수 있다.
Scala 보편적인Collection
컬렉션으로 패턴 매칭하기
패턴 매칭은 스칼라 표준 컬렉션 라이브러리의 그저 평범한 연산이 아니라 이 언어의 핵심 특징이다. 패턴 매칭은
스칼라 데이터 구조를 광범위 하게 적용될 수 있으며, 현명하게 사용한다면 다른 언어에서는 광범위한 작업이
필요한 로직을 짧고 간단하게 만들어 줄 수 있다.
스칼라 컬렉션 라이브러리를 다른 언어들과 구분 짓는 핵심 특징은 불변의 데이터 구조와 고차 연산을 지원한다는
데 있다.
스칼라 핵심 데이터 구조인 List, Map, Set은 불변하는 데이터 구조다. 이들은 크기를 재조정할 수도 없으며, 그 안의
내용을 바꿀 수도 없다.
가변적인 컬렉션 보다 우선권을 주기 위해 불변의 데이터 구조 패키지 (collection.immutable)는 자동으로 스칼라
네임스페이스에 기본적으로 임포트 된다.
Scala 보편적인Collection
컬렉션으로 패턴 매칭하기
이러한 우선권 때문에 개발자들이 일반적으로 함수형 프로그래밍 업계에서 '모범 사례'라 할 수 있는 불변의
컬렉션과 불변의 데이터를 사용하도록 유도하는 것을 목표로 한다.
익명 함수를 이용하여 컬렉션을 취하고, 이를 반복 또는 맵핑하는 능력은 루비와 파이썬을 포함한 많은 언어에서
보편적이다.
타입이 안전한 컬렉션을 고차 함수와 사용하면 선언형 프로그래밍을 지원하고, 표현력 있는 코드를 만들 수 있으며,
런타임 타입 전환 에러의 발생이 매우 적다.
스칼라 컬렉션은 모나드 구조(monadic)로, 고차원의 타입-안전한 방식으로 연산을 연결 할 수 있게 해준다.
Scala 함수적자료구조
함수적 자료구조 (빨간책)
함수적 프로그램은 변수를 갱신하거나 변이 가능한(mutable) 자료구조를 수정하는 일이 없다고 했다.
그렇다면 자연스럽게 이런 의문이 떠오를 것이다. 함수형 프로그래밍에서 사용할 수 있는 자료구조는 어떤 것일까?
함수적 자료구조의 정의
함수적 자료구조란 오직 순수 함수만으로 조작되는 자료구조이다.
순수함수는 자료를 그 자리에서 변경하거나 기타 부수 효과를 수행하는 일이 없어야 함을 기억하기 바란다.
따라서 함수적 자료구조는 정의에 의해 불변이다.
Scala 함수적자료구조
단일 연결 목록
Scala 함수적자료구조
자료 형식을 도입할 때에는 trait 키워드를 사용한다. trait 키워드로 정의하는 ‘특질(trait)’은 하나의 추상
인터페이스로, 필요하다면 일부 메서드의 구현을 담을 수도 있다.
위 코드에서는 List라는 특질을 정의했다. 이 특질에는 메서드가 없다. trait 앞에 sealed를 붙이는 것은 이 특질의
모든 구현이 반드시 이 파일 안에 선언되어야 함을 뜻한다.
그 다음에 있는 case 키워드로 시작하는 두 줄은 List의 두 가지 구현, 즉 두가지 자료 생성자(data constructor)이다
이들은 List가 취할 수 있는 두가지 형태를 나타낸다.
매개변수 A를 둔 것은 A 매개변수를 사용함으로써, 목록에 담긴 요소들의 형식에 대해 다형성이 적용되는 List 자료
형식이 만들어진다.
Int, Double, String 등 사용할 수 있게된다. 변수 A에 있는 +는 공변(covariant)을 뜻한다.
(공변과 불변은 빨간책 40p를 참조하라.)
Scala 함수적자료구조
위에서 보여준 trait으로 정의한 List에서 case Cons[+A](head : A, tail : List[A]) extends List[A] 는 Cons라는 형태가
List[A]를 상속받는 구조이다. 스칼라에서 List는 연결리스트이다.
이것을 함수형 자료구조로 나타냈을 때 Cons(head :A, tail : List[A]) 로 나타낼 수 있다는 것이다.
풀어서 이야기하면 Cons(값, 링크) 로 이해하면 편하다. 하지만 이곳에서는 결국 Cons(값,Cons(값,Cons(값,...)))
형태가 되는 것이다. 이것이 연결리스트를 함수형 자료구조로 표현한 것이다.
ex) function(value, function) 형태
Scala 함수적자료구조
패턴 부합은 표현식의 구조를 따라 내려가면서 그 구조의 부분 표현식을 추출하는 복잡한 switch문과 비슷하게
작동한다.
패턴 부합 구문은 표현식으로 시작해서 다음 키워드 match가 오고, 그 다음에 일련의 경우(case) 문들이 {}로
감싸인 형태이다.
부합의 각 경우 문은 =>의 좌변에 패턴이 있고, 우변에 결과가 있는 형태다.
대상이 경우 문의 패턴과 부합하면 그 경우 문의 결과가 전체 부합 표현식의 결과가 된다.
만일 대상과 부합하는 패턴이 여러 개이면 스칼라는 처음으로 부합하는 경우 문을 선택한다.
ex)
List(1,2,3) match { case _ => 42 } 이 패턴식에는 결국 42가 된다.
임의 표현식 _ 를 사용했기 때문에 any 타입으로도 매치가 됨으로 42가 된다.
(‘_’ 대신 x나 foo를 사용해도 되지만, 경우 문의 결과 안에서 그 값이 무시되는 변수를 나타낼 때에는 이처럼 ‘_’를
사용하는 것이 보통이다.)
Scala 함수적자료구조
List(1, 2, 3) match { case Cons(_, t) => t } 결과는 무엇일까?
답은 List(2, 3) 이다. 위 case문은 head를 제외한 tail만 반환하라는 뜻이다.
List(1, 2, 3) match { case Nil => 42 } 결과는 무엇일까?
답은 MatchError 이다. Nil ( null) 이다. 따라서 List가 Nil 이 아니기 부합되는 것이 하나도 없음을 뜻한다.
아래 문제를 한번 풀어보자.
다음 패턴 부합 표현식의 결과는 무엇인가?
val x = List(1, 2, 3, 4, 5) match {
case Cons(x, Cons(2, Cons(4, _))) => x
case Nil => 42
case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
case Cons(h, t) => h + sum(t)
case _ => 101
}
Scala 참고 도서
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&barcode=9791185890791
http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791185890180

More Related Content

PDF
러닝스칼라 - Scala 기초 (1)
PDF
Scala 기초 (2)
PPTX
동작 파라미터와 람다 In java 8
PDF
Start IoT with JavaScript - 5.객체2
PPTX
자바 8 학습
PDF
자바8강의 2강. Stream API
PDF
Scala 기초 (3)
PDF
자바8강의 1강. lambda expression
러닝스칼라 - Scala 기초 (1)
Scala 기초 (2)
동작 파라미터와 람다 In java 8
Start IoT with JavaScript - 5.객체2
자바 8 학습
자바8강의 2강. Stream API
Scala 기초 (3)
자바8강의 1강. lambda expression

What's hot (20)

PDF
자바8강의 0강. java8 overview
PDF
Start IoT with JavaScript - 4.객체1
PDF
Start IoT with JavaScript - 6.함수
PPTX
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
PDF
Start IoT with JavaScript - 2.연산자
PDF
Lambda 란 무엇인가
PDF
Haskell study 3
PDF
나에 첫번째 자바8 람다식 지앤선
PDF
Java8 & Lambda
PDF
Java 8 api :: lambda 이용하기
PPTX
이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)
PDF
Start IoT with JavaScript - 1.기초
PDF
Haskell study 2
PPTX
이것이 자바다 Chap.11 기본 API 클래스(java)(KOR)
PDF
자바8 람다 나머지 공개
PDF
Haskell study 6
PDF
STL study (skyLab)
PDF
자바8 람다식 소개
PDF
9 swift 클로저1
PPTX
Java8 람다
자바8강의 0강. java8 overview
Start IoT with JavaScript - 4.객체1
Start IoT with JavaScript - 6.함수
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
Start IoT with JavaScript - 2.연산자
Lambda 란 무엇인가
Haskell study 3
나에 첫번째 자바8 람다식 지앤선
Java8 & Lambda
Java 8 api :: lambda 이용하기
이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)
Start IoT with JavaScript - 1.기초
Haskell study 2
이것이 자바다 Chap.11 기본 API 클래스(java)(KOR)
자바8 람다 나머지 공개
Haskell study 6
STL study (skyLab)
자바8 람다식 소개
9 swift 클로저1
Java8 람다
Ad

Similar to Scala 기초 (4) (20)

PDF
스칼라와 스파크 영혼의 듀오
PDF
Scala
PDF
[D2 campus seminar]스칼라를 통한 다양한 언어의 패러다임 맛보기
PDF
Haskell study 5
PPTX
자바프로그래머를 위한 스칼라
PPTX
Feel functional
PPTX
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
PDF
Scala, Scalability
PDF
Scalability
PPTX
파이썬 Collections 모듈 이해하기
PPTX
Sicp 2.2 계층 구조 데이터와 닫힘 성질
PDF
세일즈포스 서울 어드민 그룹 Trigger 연재 강의 (반복문/조건문)
PDF
Collection framework
PDF
데이터 분석 3 - Java Collection Framework와 ArrayList
PDF
자바8 스트림 API 소개
PPTX
함수형 사고 - Functional thinking
PDF
Python Programming: Type and Object
PPTX
하스켈 프로그래밍 입문
PPTX
함수형 프로그래밍 언어 스칼라(Scala) 소개
PDF
함수적 사고 2장
스칼라와 스파크 영혼의 듀오
Scala
[D2 campus seminar]스칼라를 통한 다양한 언어의 패러다임 맛보기
Haskell study 5
자바프로그래머를 위한 스칼라
Feel functional
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
Scala, Scalability
Scalability
파이썬 Collections 모듈 이해하기
Sicp 2.2 계층 구조 데이터와 닫힘 성질
세일즈포스 서울 어드민 그룹 Trigger 연재 강의 (반복문/조건문)
Collection framework
데이터 분석 3 - Java Collection Framework와 ArrayList
자바8 스트림 API 소개
함수형 사고 - Functional thinking
Python Programming: Type and Object
하스켈 프로그래밍 입문
함수형 프로그래밍 언어 스칼라(Scala) 소개
함수적 사고 2장
Ad

Scala 기초 (4)

  • 2. Scala 보편적인Collection 컬렉션 프레임워크는 배열, 리스트, 맵, 집합, 트리와 같이 주어진 타입을 가지는 하나 또는 그 이상의 값을 수집하는 데이터 구조를 제공한다. 스칼라는 JVM 언어이므로 스칼라 코드에서 자바 컬렉션 라이브러리 전체에 접근 하고 사용할 수 있다. 물론, 그렇게 한다면 스칼라만이 가지고 있는 컬렉션의 고차 연산이 주는 영광을 놓치게 된다. 스칼라도 자바와 마찬가지로 고성능의, 객체지향적인, 타입-매개변수화된 컬렉션 프레임워크를 가지고 있다. 그러나 스칼라의 컬렉션은 map, filter, reduce와 같이 짧고 표현력이 있는 표현식으로 데이터를 관리하고 처리하는 고차 연산도 가지고 있다. 또한, 가변적인 컬렉션 타입 계층구조와 불변의 컬렉션 타입 계층구조를 별개로 가지고 있어서(안정성을 위한) 불변의 데이터와 (필요하다면) 가변적인 데이터 사이의 전환을 쉽게 만들어준다.
  • 3. Scala 보편적인Collection 리스트 리스트는 이것을 함수로 호출함으로써 생성할 수 있다. 호출 사이에 그 리스트에 포함될 내용을 쉼표로 구분된 매개변수 형태로 전달한다. Lisp 스타일의 head()와 tail() 메소드를 사용하여 리스트의 첫 번째 요소와 나머지 요소에 각각 접근해보자. 직접 단일 요소에 접근하려면, 리스트를 함수로 호출하고 그 요소를 가리키는 0부터 시작하는 인덱스를 그 함수에 전달하면 된다.
  • 5. Scala 보편적인Collection - foreach() 는 함수 (정확하게는 프로시저)를 취하고, 그 함수를 리스트의 모든 항목으로 호출한다. - map()은 단일 리스트 요소를 다른 값이나 타입으로 전환하는 함수를 취한다. - reduce()는 두 리스트 요소를 단일 항목으로 결합하는 함수를 취한다. 리스트 foreach(), map(), reduce()를 이용한 예제. 각 함수는 리스트를 반복하고, 전환하며, 리스트를 단일 항목으로 축소한다. 각 메소드에는 함수 리터럴이 전달되는데, 이 함수 리터럴에는 괄호로 묶인 입력 매개변수와 함께 본문이 포함되어 있다.
  • 6. Scala 보편적인Collection Set set은 유일한 요소들로 이루어진 순서가 없는 불변의 컬렉션이지만, List와 유사하게 동작한다.
  • 7. Scala 보편적인Collection Map Map은 불변의 키-값 저장소로, 다른 언어에서는 해시맵(hashmap), 딕셔너리(dictionary) 또는 연관 배열 (associative array)로 알려져 있다. Map에 주어진 유일한 키로 저장된 값을 그 키를 이용하여 추출할 수 있다. 키와 값은 타입-매개변수화되어 여러분은 정수를 문자열에 매핑하는 것처럼 쉽게 문자열을 정수에 매핑할 수 있다. Map은 생성할 때 키-값 쌍을 튜플로 기술하면 된다. 키와 값 튜플을 기술하기 위해 관계 연산자(->)를 사용 할 수 있다.
  • 8. Scala 보편적인Collection 리스트에는 무엇이 있는가? List는 불변의 재귀적인 데이터 구조이므로 리스트의 각 요소는 자신만의 헤드와 점진적으로 더 짧아지는 테일을 가진다. 이를 사용하여 헤드로 시작하여 잇따른 tail들이 지나가는 길을 만들면서 여러분만의 List 반복자(iterator)를 만들 수 있다. 리스트에서 null로 표현될 수 있는 Nil은 근본적으로 List[Nothing]의 싱글턴 인스턴스다. Nothing 타입의 리스트는 따라서 다른 모든 타입의 리스트와 호환됨, 그들의 종점으로 안전하게 사용될 수 있다.
  • 9. Scala 보편적인Collection 생성 연산자 리스트를 생성하는 다른 방법으로는 이전 절에서 설명한 Nil과의 관계를 이용하는 것이다. Lisp를 인정하는 또 다른 의미로, 스칼라는 리스트를 만들기 위해 생성(cons, construct의 축양형)연산자의 사용을 지원한다. Nil을 기반으로 항목들을 결합하기 위해 오른쪽 결합형(right-associative) 생성 연산자 ::를 상용하여 전형적인 List(...) 리스트를 만들 수 있다.
  • 10. Scala 보편적인Collection 리스트의 산술연산 아래 링크 참조. http://www.scala-lang.org/api/2.7.3/scala/List.html 위의 표에서 고차 함수를 발견했는가? 아래 스칼라 REPL에서 실행된 고차 연산 세가지 예제, fitler, partition, sortBy가 있다.
  • 11. Scala 보편적인Collection 리스트의 산술연산 sortBy 메소드는 리스트 항목들의 순서를 정렬하기 위해 사용할 값을 반환하는 함수를 취하는 반면, filter와 partition 메소드는 조건자 함수를 취한다. 조건자 함수 (predicate function)는 하나의 입력값을 받아서 참 또는 거짓을 반환한다. 이 산술 연산자 메소드에서 중요한 점은 ::, drop, take가 리스트의 앞에서 동작하고, 따라서 성능상의 불이익이 없다는 것이다. List는 연결 리스트이기 때문에 그 앞에 항목들을 추가하거나, 그 앞의 항목들을 제거하는 것은 리스트 전체를 순회할 필요가 없다. 리스트가 짧다면 리스트 순회는 사소한 일이겠지만, 수천, 수백만의 항목들을 가진 리스트라면 리스트를 순회해야 하는 연산은 큰일이 될 수 있다. 그렇다고 해도 이러한 연산들은 리스트의 끝에서 동작하는, 따라서 리스트 전체 순회가 필요한 동반 연산(corollary operation)들을 가지고 있다. 대규모 리스트로 작업하지 않는 한 메모리 활용을 고려할 필요는 없지만, 일반적으로 리스트의 끝이 아니라 앞에서 연산하는 것이 가장 좋다.
  • 12. Scala 보편적인Collection 리스트 맵핑 Map 메소드는 함수를 취하여 그 함수를 리스트의 모든 요소들에 적용하고, 그 결과를 새로운 리스트에 수집한다. 일반적으로 집합 이론과 수학 분야에서는 매핑한다(map)는 것은 한 집합의 각 요소와 다른 집합의 각 요소 사이에 연관성을 만드는 것이다. collect : 각 요소를 부분 함수를 사용하여 변환하고, 해당 함수를 적용할 수 있는 요소를 유지함. flatMap : 주어진 함수를 이용하여 각 요소를 변환하고, 그 결과 리스트를 이 리스트에 평면화(flatten)함. map : 주어진 함수를 이용하여 각 요소를 변환함.
  • 13. Scala 보편적인Collection 리스트 축소하기 리스트 축소는 컬렉션으로 작업하는 데 있어 가장 보편적인 연산이다/ 등급 리스트를 합산하거나 여러 성능 테스트 결과의 평균 시간을 계산해야 하는가? 만일 컬렉션이 특정 요소를 포함하는지 검사하고 싶거나, 조건자 함수가 리스트의 모든 요소에 대해 '참'을 반환할 것인지를 알고 싶다면? 이들은 리스트를 단일 값으로 축소하는 로직을 사용하기 때문에 모두 리스트 축소 연산이다. 스칼라의 컬렉션은 수학적 축소 연산(예: 리스트의 합계 구하기)과 부울 축소 연산(예: 리스트가 주어진 요소를 포함하는 여부 확인하기)을 지원한다. max : 리스트의 최댓값 구하기. min : 리스트의 최솟값 구하기. product : 리스트의 숫자들을 곱하기 sum : 리스트의 숫자들을 합산하기
  • 14. Scala 보편적인Collection 리스트 축소하기 contains : 리스트가 이 요소를 포함하고 있는지를 검사함. endWith : 리스트가 주어진 리스트로 끝나는지를 검사함. exists : 리스트에서 최소 하나의 요소에 대해 조건자가 성립하는지를 검사함. forall : 리스트의 모든 요소에 대해 조건자가 성립하는지를 검사함. startsWith : 리스트가 주어진 리스트로 시작하는지를 테스트 함.
  • 15. Scala 보편적인Collection 리스트 축소하기 리스트를 입력 함수 기반으로 축소하는 고차 함수를 속칭 리스트-접기(list-folding)연산이라 하는데, 리스트를 축소하는 함수는 접기(fold)로 더 잘 알려져 있기 때문이다.
  • 16. Scala 보편적인Collection 컬렉션 전환하기 스칼라에서는 타입 간 전환이 쉬워서 하나의 타입으로 설렉션을 생성하여 다른 타입으로 끝낼 수 있다. mkString : 주어진 구분자를 사용하여 컬렉션을 String으로 만듬 ex ) List(24, 99, 104).mkString(", ") toBuffer : 불변의 컬렉션을 가변적인 컬렉션으로 전환 ex ) list('f', 't').toBuffer toList : 컬렉션을 List로 전환 ex ) Map("a" -> 1, "b" -> 2).toList toMap : 두 요소(길이)로 구성된 튜플의 컬렉션을 Map으로 전환 ex) Set(1 -> true, 3 -> true).toMap toSet : 컬렉션을 Set으로 전환 ex) List(2, 5, 5, 3, 2).toSet toString : 컬렉션을 String으로 컬렉션의 타입을 포함하여 만듦. ex ) List(2, 5, 5, 3, 2).toString
  • 17. Scala 보편적인Collection 자바와 스칼라 컬렉션 호환성 자바와 스칼라 상호작용의 일부는 자바 컬렉션과 스칼라 컬렉션 간 전환하는 것인데, 이 두 컬렉션 타입은 기본적으로 호환되지 않는다. import 명령어는 JavaConverters와 그 메소드를 현재의 네임스페이스에 추가한다. asJava : 스칼라와 컬렉션을 그에 대응하는 자바 컬렉션으로 전환함. ex) List(12, 29).asJava asScala : 이 자바컬렉션을 그에 대응하는 스칼라 컬렉션으로 전환함. ex) new java.util.ArrayList(5).asScala
  • 18. Scala 보편적인Collection 컬렉션으로 패턴 매칭하기 패턴 가드에서 와일드 카드('_')로 컬렉션의 일부 또는 모든 요소에 값을 바인딩 할 수 있다.
  • 19. Scala 보편적인Collection 컬렉션으로 패턴 매칭하기 패턴 매칭은 스칼라 표준 컬렉션 라이브러리의 그저 평범한 연산이 아니라 이 언어의 핵심 특징이다. 패턴 매칭은 스칼라 데이터 구조를 광범위 하게 적용될 수 있으며, 현명하게 사용한다면 다른 언어에서는 광범위한 작업이 필요한 로직을 짧고 간단하게 만들어 줄 수 있다. 스칼라 컬렉션 라이브러리를 다른 언어들과 구분 짓는 핵심 특징은 불변의 데이터 구조와 고차 연산을 지원한다는 데 있다. 스칼라 핵심 데이터 구조인 List, Map, Set은 불변하는 데이터 구조다. 이들은 크기를 재조정할 수도 없으며, 그 안의 내용을 바꿀 수도 없다. 가변적인 컬렉션 보다 우선권을 주기 위해 불변의 데이터 구조 패키지 (collection.immutable)는 자동으로 스칼라 네임스페이스에 기본적으로 임포트 된다.
  • 20. Scala 보편적인Collection 컬렉션으로 패턴 매칭하기 이러한 우선권 때문에 개발자들이 일반적으로 함수형 프로그래밍 업계에서 '모범 사례'라 할 수 있는 불변의 컬렉션과 불변의 데이터를 사용하도록 유도하는 것을 목표로 한다. 익명 함수를 이용하여 컬렉션을 취하고, 이를 반복 또는 맵핑하는 능력은 루비와 파이썬을 포함한 많은 언어에서 보편적이다. 타입이 안전한 컬렉션을 고차 함수와 사용하면 선언형 프로그래밍을 지원하고, 표현력 있는 코드를 만들 수 있으며, 런타임 타입 전환 에러의 발생이 매우 적다. 스칼라 컬렉션은 모나드 구조(monadic)로, 고차원의 타입-안전한 방식으로 연산을 연결 할 수 있게 해준다.
  • 21. Scala 함수적자료구조 함수적 자료구조 (빨간책) 함수적 프로그램은 변수를 갱신하거나 변이 가능한(mutable) 자료구조를 수정하는 일이 없다고 했다. 그렇다면 자연스럽게 이런 의문이 떠오를 것이다. 함수형 프로그래밍에서 사용할 수 있는 자료구조는 어떤 것일까? 함수적 자료구조의 정의 함수적 자료구조란 오직 순수 함수만으로 조작되는 자료구조이다. 순수함수는 자료를 그 자리에서 변경하거나 기타 부수 효과를 수행하는 일이 없어야 함을 기억하기 바란다. 따라서 함수적 자료구조는 정의에 의해 불변이다.
  • 23. Scala 함수적자료구조 자료 형식을 도입할 때에는 trait 키워드를 사용한다. trait 키워드로 정의하는 ‘특질(trait)’은 하나의 추상 인터페이스로, 필요하다면 일부 메서드의 구현을 담을 수도 있다. 위 코드에서는 List라는 특질을 정의했다. 이 특질에는 메서드가 없다. trait 앞에 sealed를 붙이는 것은 이 특질의 모든 구현이 반드시 이 파일 안에 선언되어야 함을 뜻한다. 그 다음에 있는 case 키워드로 시작하는 두 줄은 List의 두 가지 구현, 즉 두가지 자료 생성자(data constructor)이다 이들은 List가 취할 수 있는 두가지 형태를 나타낸다. 매개변수 A를 둔 것은 A 매개변수를 사용함으로써, 목록에 담긴 요소들의 형식에 대해 다형성이 적용되는 List 자료 형식이 만들어진다. Int, Double, String 등 사용할 수 있게된다. 변수 A에 있는 +는 공변(covariant)을 뜻한다. (공변과 불변은 빨간책 40p를 참조하라.)
  • 24. Scala 함수적자료구조 위에서 보여준 trait으로 정의한 List에서 case Cons[+A](head : A, tail : List[A]) extends List[A] 는 Cons라는 형태가 List[A]를 상속받는 구조이다. 스칼라에서 List는 연결리스트이다. 이것을 함수형 자료구조로 나타냈을 때 Cons(head :A, tail : List[A]) 로 나타낼 수 있다는 것이다. 풀어서 이야기하면 Cons(값, 링크) 로 이해하면 편하다. 하지만 이곳에서는 결국 Cons(값,Cons(값,Cons(값,...))) 형태가 되는 것이다. 이것이 연결리스트를 함수형 자료구조로 표현한 것이다. ex) function(value, function) 형태
  • 25. Scala 함수적자료구조 패턴 부합은 표현식의 구조를 따라 내려가면서 그 구조의 부분 표현식을 추출하는 복잡한 switch문과 비슷하게 작동한다. 패턴 부합 구문은 표현식으로 시작해서 다음 키워드 match가 오고, 그 다음에 일련의 경우(case) 문들이 {}로 감싸인 형태이다. 부합의 각 경우 문은 =>의 좌변에 패턴이 있고, 우변에 결과가 있는 형태다. 대상이 경우 문의 패턴과 부합하면 그 경우 문의 결과가 전체 부합 표현식의 결과가 된다. 만일 대상과 부합하는 패턴이 여러 개이면 스칼라는 처음으로 부합하는 경우 문을 선택한다. ex) List(1,2,3) match { case _ => 42 } 이 패턴식에는 결국 42가 된다. 임의 표현식 _ 를 사용했기 때문에 any 타입으로도 매치가 됨으로 42가 된다. (‘_’ 대신 x나 foo를 사용해도 되지만, 경우 문의 결과 안에서 그 값이 무시되는 변수를 나타낼 때에는 이처럼 ‘_’를 사용하는 것이 보통이다.)
  • 26. Scala 함수적자료구조 List(1, 2, 3) match { case Cons(_, t) => t } 결과는 무엇일까? 답은 List(2, 3) 이다. 위 case문은 head를 제외한 tail만 반환하라는 뜻이다. List(1, 2, 3) match { case Nil => 42 } 결과는 무엇일까? 답은 MatchError 이다. Nil ( null) 이다. 따라서 List가 Nil 이 아니기 부합되는 것이 하나도 없음을 뜻한다. 아래 문제를 한번 풀어보자. 다음 패턴 부합 표현식의 결과는 무엇인가? val x = List(1, 2, 3, 4, 5) match { case Cons(x, Cons(2, Cons(4, _))) => x case Nil => 42 case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y case Cons(h, t) => h + sum(t) case _ => 101 }