문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
비동기_프로그래밍과_scala [2020/08/09 07:21] cumul0529 Eager evaluation의 번역을 원어로 변경 |
비동기_프로그래밍과_scala [2020/08/09 07:39] (현재) cumul0529 [함수형 프로그래밍과 타입 클래스] 마크업 수정 |
||
---|---|---|---|
줄 177: | 줄 177: | ||
</ | </ | ||
- | 바로 이것이 비결정론의 실례(實例)입니다. 두 개의 작업이 종료되는 순서가 보장되지 않기 때문에 우리는 동기화를 수행하는 소규모의 상태 기계(state machine)를 구현해야 합니다. | + | 바로 이것이 비결정론의 실제 예시입니다. 두 개의 작업이 종료되는 순서가 보장되지 않기 때문에 우리는 동기화를 수행하는 소규모의 상태 기계(state machine)를 구현해야 합니다. |
먼저 상태 기계의 ADT를 정의합니다. | 먼저 상태 기계의 ADT를 정의합니다. | ||
줄 444: | 줄 444: | ||
// 값 변형 | // 값 변형 | ||
def map[U](f: T => U)(implicit ec: ExecutionContext): | def map[U](f: T => U)(implicit ec: ExecutionContext): | ||
+ | |||
// 연속 실행 ;-) | // 연속 실행 ;-) | ||
def flatMap[U](f: | def flatMap[U](f: | ||
+ | |||
// ... | // ... | ||
} | } | ||
줄 452: | 줄 454: | ||
'' | '' | ||
- | * [[https:// | + | * [[https:// |
* [[https:// | * [[https:// | ||
* 단일한 값을 흘려보내고(stream) 나타냅니다(show). 메모아이제이션이 적용되었기 때문입니다. 따라서 작업 완료에 대한 소비자(listener)는 최대 한 번까지만 호출됩니다. | * 단일한 값을 흘려보내고(stream) 나타냅니다(show). 메모아이제이션이 적용되었기 때문입니다. 따라서 작업 완료에 대한 소비자(listener)는 최대 한 번까지만 호출됩니다. | ||
줄 635: | 줄 637: | ||
===== Task와 Scala의 IO 모나드 ===== | ===== Task와 Scala의 IO 모나드 ===== | ||
- | '' | + | '' |
[[https:// | [[https:// | ||
줄 647: | 줄 649: | ||
요약하자면 '' | 요약하자면 '' | ||
- | * 느긋하고 비동기적인 연산을 표현합니다. | + | * Lazy하고 비동기적인 연산을 표현합니다. |
* 하나 혹은 여러 개의 소비자(consumer)에게 오직 하나의 값만을 전달하는 생산자(producer)를 표현합니다. | * 하나 혹은 여러 개의 소비자(consumer)에게 오직 하나의 값만을 전달하는 생산자(producer)를 표현합니다. | ||
- | * 느긋하게 계산되기 때문에, '' | + | * Lazy evaluation을 수행하기 때문에, '' |
* 메모아이제이션이 가능합니다. | * 메모아이제이션이 가능합니다. | ||
* 반드시 다른 논리 스레드에서 실행되어야 하는 것은 아닙니다. | * 반드시 다른 논리 스레드에서 실행되어야 하는 것은 아닙니다. | ||
줄 670: | 줄 672: | ||
==== 연속 실행 ==== | ==== 연속 실행 ==== | ||
- | [[비동기_프로그래밍과_scala&do=# | + | [[비동기_프로그래밍과_scala# |
<code scala> | <code scala> | ||
줄 688: | 줄 690: | ||
</ | </ | ||
- | 이 코드는 '' | + | 이 코드는 '' |
이제 [[비동기_프로그래밍과_scala# | 이제 [[비동기_프로그래밍과_scala# | ||
줄 724: | 줄 726: | ||
// 나쁜 예 (이 코드는 여전히 연속 실행됩니다) | // 나쁜 예 (이 코드는 여전히 연속 실행됩니다) | ||
def timesFour(n: | def timesFour(n: | ||
- | // Task는 | + | // Task는 |
val fa = timesTwo(n) | val fa = timesTwo(n) | ||
val fb = timesTwo(n) | val fb = timesTwo(n) | ||
- | // 느긋한 계산으로 인해 값이 연속으로 계산됩니다. | + | // Lazy evaluation으로 인해 값이 연속으로 계산됩니다. |
for (a <- fa; b <- fb) yield a + b | for (a <- fa; b <- fb) yield a + b | ||
} | } | ||
줄 745: | 줄 747: | ||
'' | '' | ||
- | '' | + | '' |
<code scala> | <code scala> | ||
줄 774: | 줄 776: | ||
그렇다면 '' | 그렇다면 '' | ||
- | 가능합니다. 우리는 이미 순차 실행을 추상화하는 '' | + | 가능합니다. 우리는 이미 순차 실행을 추상화하는 '' |
마침 Scala는 상류 타입(higher kinded types)을 지원하는 몇 안되는 언어에 속하고 [[https:// | 마침 Scala는 상류 타입(higher kinded types)을 지원하는 몇 안되는 언어에 속하고 [[https:// | ||
줄 782: | 줄 784: | ||
> 하지만 그러한 설명 방식은 Scala와 사용자 모두에게 민폐입니다. 다른 언어에서 저 개념들은 단순히 설명하기 어려운 디자인 패턴에 불과합니다. 대부분의 다른 언어들은 형에 대한 표현성이 부족하기 때문입니다. 저 개념들을 표현할 수 있는 언어는 손에 꼽습니다. 언어 사용자의 입장에서도 문제가 생겼을 때 저 개념들을 모른 채 관련된 자료를 검색하는 것은 매우 고통스러운 일입니다. | > 하지만 그러한 설명 방식은 Scala와 사용자 모두에게 민폐입니다. 다른 언어에서 저 개념들은 단순히 설명하기 어려운 디자인 패턴에 불과합니다. 대부분의 다른 언어들은 형에 대한 표현성이 부족하기 때문입니다. 저 개념들을 표현할 수 있는 언어는 손에 꼽습니다. 언어 사용자의 입장에서도 문제가 생겼을 때 저 개념들을 모른 채 관련된 자료를 검색하는 것은 매우 고통스러운 일입니다. | ||
> | > | ||
- | > 또 저는 이것이 모르는 것에 대한 본능적인 공포에서 나오는 일종의 [[https:// | + | > 또 저는 이것이 모르는 것에 대한 본능적인 공포에서 나오는 일종의 [[https:// |
==== Monad (연속 실행과 재귀 실행) ==== | ==== Monad (연속 실행과 재귀 실행) ==== |