Java야 뭐, 기존 타입이 functional programming에 적합하지 않기 때문에, Array, List, Set 등등의 타입을 다 Java 8부터 제공하는 Stream으로 변환해놓고 처리하니까...
import java.util.*;
import java.util.stream.*;
public class A {
public static void main(String[] args) {
// 1. Array
String[] ss = { "1", "2", "3" };
Stream.of(ss)
.map(s -> Integer.valueOf(s))
.forEach(i -> System.out.println("Value: " + i + " (" + i.getClass().getName() + ")"));
// 2. List
List<String> sl = Arrays.asList("1", "2", "3");
sl.stream()
.map(s -> Integer.valueOf(s))
.forEach(i -> System.out.println("Value: " + i + " (" + i.getClass().getName() + ")"));
// 3. Set
Set<String> ss = Set.of("1", "2", "3"); // java 9
ss.stream()
.map(s -> Integer.valueOf(s))
.forEach(i -> System.out.println("Value: " + i + " (" + i.getClass().getName() + ")"));
// X. 그 외 Map 등은 생략
}
}
Scala는 알아보기도 힘든-.- 시그니처를 가진 map()을 호출하고나면 원래의 타입을 리턴한다. 정확히는 모르겠지만, List, Set, Array 등의 내부에 정의되어있는 map()에서 implicit으로 사용하는 CanBuildFrom 덕분에 원래 타입이 유지되는 것으로 보인다. (자세히 아시는 분 있으면 코멘트 부탁드립니다!)
final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = ???
class GenericCanBuildFrom[A](implicit tag: ClassTag[A]) extends CanBuildFrom[CC[_], A, CC[A]]
근데 왜 Kotlin은 어떤 타입에서 시작하든 map의 결과가 List가 되는걸까. 아예 Iterable.map()의 시그니처에 리턴 타입이 List라고 정의되어있다. (link to Kotlin Reference - map)
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>
Kotlin에서는 map()이 단순 functor가 아닌가보다...라고 생각하면 되긴 하는데 완전 별로다 -_- List가 아닌 다른 Collection의 요소에 어떤 함수를 적용한 후 그 타입을 그대로 가지고 싶으면 어떻게 해야 하지?_?
----
추가: Kotlin의 Sequence라는 타입이 Java로 치면 Stream 같은 역할을 수행한다고 한다. (sequential data의 lazy evaluation)
이 타입에서는 (중간(intermediate) 연산들을 수행한 후) 종료(terminal) 연산할 때 최종 타입이 정해진다. 그러므로 monad인 것 처럼 사용할 수 있다.
public fun <T> Sequence<T>.toList(): List<T> {
return this.toMutableList().optimizeReadOnlyList()
}
public fun <T> Sequence<T>.toSet(): Set<T> {
return toCollection(LinkedHashSet<T>()).optimizeReadOnlySet()
}
public inline fun <T, K, V> Sequence<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V> {
return associateTo(LinkedHashMap<K, V>(), transform)
}
public inline fun <T, K> Sequence<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> {
return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)
}
'Programming Languages' 카테고리의 다른 글
이상한 Kotlin의 세계 - Type inference (0) | 2020.05.17 |
---|---|
Scala Option (0) | 2017.01.29 |
[추상자료형] 리스트(List) (0) | 2016.09.18 |