1. Map에서 값을 꺼내올때
제일 당황스러웠던 것 중 하나가 아래의 경우였다.
for{
k <- some List K
L <- some Map M.get(k)
c <- Some List L}
yield c
// M은 list를 value로 갖는 Map이다
간단히 말해서
List K에서 원소(k)를 뽑아서,
k에 해당하는 값(List L)을 Map M에서 찾아서
L의 원소 c를 가져오는 코드이다.
위에서 당연히 c에 L의 원소가 들어간다고 생각했는데, 그렇지 않았다.
두번째 줄 Map에서 원소를 꺼내 올때, 리스트가 나오는 것이 아니라 Some(value 인 List L) 형태로 나온다.
Map에 key가 없는 경우 때문에 이렇게 동작한는 것 같다.
그래서 Some을 unbind하기 위해서 getOrElse()를 사용해야한다.
그런데 나는 여기서 getOrElse()를 바로 사용하면 내 로직 상의 문제로 원하는대로 동작하지 않았다...
그렇지만 some에서 값을 꺼내오기 위해서는 어디선가 getOrElse()를 써야했고,
getOrElse에 None은 에러가 나고 List()는 생각과 다르게 동작하고, 난장 대잔치였다...
2. 빈 리스트 : List()에서 값을 꺼내올 때
List()는 값이 없기 때문에, 값을 꺼낸 뒤에 일어나는 operation들은 수행되지 않는다.
빈 리스트에 map을 하면 아무 일도 안 일어나는 것을 생각하면
(return값이 빈 리스트 List()이다. 전달한 함수 자체가 실행되지 않는다.)
당연한 부분인데, 일단 for {...} yield가 map으로 바뀐다는 것을 생각조차 못하고 있었으니...
전혀 생각하지 못한 부분이었다.
잘 모를 때는, line by line으로 하나씩 print해보자
3. =과 <-의 차이
yield를 사용하는지 여부에 따라 return 값이 scala인지 vector인지 결정된다.
그래서인지 {} 내부에서 <-를 사용할 수 있을 때와 없을 때가 있었다.
아직 정확히 파악은 못했지만, Map처럼 값을 꺼내올 때, Nothing일 수 있는 경우에는 =을 사용할 수 없는 것 같다.
1번에서 고생할 때, <-를 =로도 바꿔보기도 했는데 compile error가 나는 경우도 있었다.
반대로 yield가 없을 때 <-에서 에러가 나고 =가 잘 작동하는 경우도 있었다.
아직 잘 모르겠다 ㅠㅠㅠ 이건 좀 더 공부해봐야겠다.
Monad에 대한 이해가 더 필요한 부분인가 싶기도 하고...
하나씩 정리하다보면 조금 알지 않을까 싶다...
일단은 for 문이 어떤 function으로 변환되는지를 이해하는 것이
제대로 작동하는 코드를 작성하는 첫걸음인 것 같다.
'언어 > Scala' 카테고리의 다른 글
Scala class, constructor(생성자), new, instance (0) | 2020.02.13 |
---|---|
Reactive Programming, Functional programming, Reactive Principles (0) | 2020.02.08 |
scala for comprehension, for {...} yield (0) | 2020.02.03 |
type / class 확인하기 (0) | 2020.01.26 |
for{...} yield 이해하기2 (0) | 2020.01.26 |