Monads
A structure that puts a value in a computational context.
이것도 제대로 된 개념은 아니다. 수학적으로 어려운 개념이라 한 줄로 딱 정의하기가 어렵다고 한다.
나는 일단, 객체이면서 content가 있을지 없을지 모르는 상태까지 포함하는 개념이라고 이해하도록 하겠다.
Monads에는 unit과 bind의 역할을 하는 함수들이 있는데 대충 어떤 건지는 예시를 보면 알 수 있다. stepik에서도 여기서 설명은 안할거니까 너가 구글링해서 찾아봐~! 라고 한다.
Java에서 Monads의 역할을 하는 것에는 Optional과 Stream이 있다. Stream은 전에 했던거니까 Optional만 가져온다.
Optional
Optional<T> encapsulates the presence or absence of a value of type T. The instance of Optional<T> may be empty or non-empty. It allows you to avoid null reference and reduces boilerplate code for checking nulls.
Optional은 인턴할 때도 많이 썼다!
NPE 나는 걸 막아주기 위해 객체를 한 번 더 보호해주는 거라고 생각하면 쉽다.
Map (User -> User.getAccount()) : Optional<Account>
flatMap(User -> Optional<Account>) : Optional<Account>
Map과 flatMap이 다른 점은 Map은 return값이 value인 함수만 인자로 받는다는 것!
return값에 Optional이 씌워져 있으면 안된다.
그럼 이제 어려웠던 문제를 보자.
Using the method you've written for finding an user by their login, write a new method printBalanceIfNotEmpty(String userLogin)that prints an account balance for an existing user if `balance > 0`. In this case, the result format should print the string:
login: balance
If the user is not found, account is null or the balance = 0, then the method should not print anything.
Do not forget to use optional for avoiding NPE.
public static void printBalanceIfNotEmpty(String userLogin) {
Optional<User>target = findUserByLogin(userLogin);
if(target.isPresent()){
Optional<Account> targetAcc =
Optional.ofNullable(target.get().getAccount());
if(targetAcc.isPresent() && targetAcc.get().getBalance()>0){
System.out.printf("%s: %d",userLogin, target.get().getAccount().getBalance());
}
}
}
이 코드는 더 간단하게 다음과 같이 짤 수 있다.
public static void printBalanceIfNotEmpty(String userLogin) {
findUserByLogin(userLogin)
.flatMap(user -> Optional.ofNullable(user.getAccount()))
.filter(acc -> acc.getBalance() > 0) // Optional<Account> : Optional.empty()
.ifPresent(acc -> System.out.printf("%s: %d",userLogin, acc.getBalance()));
}
if 자체가 Monad에선 굳이 필요가 없다!
그냥 함수로 리턴되는 값에다가 flatMap로 User에서 Account 가져오고, filter이용해서 balance>0 인 것들만 거르고, ifPresent에다가 consumer 넣어주면 print까지 된다.
쩌업,,, 풀긴 풀었는데 효율적인 방법으로 푼 건 아니라 그냥 이상적인 모범답안을 가져왔다
출처 : https://stepik.org/course/1595
Java. Functional programming
The course introduces elements of functional programming in Java 8. After completing this course, you should have a basic understanding of lambda expressions, functional interfaces, stream API, lazy evaluation, currying and monads.
stepik.org
음,, 이것도 오답노트라고 할 수 있나,,,?
'CS > Java' 카테고리의 다른 글
| Java FP 4. Currying (5) | 2020.04.07 |
|---|---|
| Java FP 3. Streams (4) | 2020.03.30 |
| Java FP 2. Functions are objects (13) | 2020.03.26 |
| Java FP 1. Lambda expressions and method references (14) | 2020.03.26 |