Functor는 기본적인 객체로서 객체 내의 각 값을 실행할 때 같은 객체를 return하는 map interface를 구현한 것이다.
Array도 일종의 functor다.
어떤 객체의 안에 있는 값을 내부 메서드 map을 통해서 객체안의 다른 타입으로 바꾸는 것이다.
import java.util.function.Function;
interface Functor<T> {
<R> Functor<R> map(Function<T, R> f);
}
즉 Functer는 map 함수를 들고 있는 인터페이스다.
함수가 리턴한 R을 새로운 Functor 객체에 감싸서 반환한다. 2개 파라미터 가지고 Mapping 함수 적용 방식을 아는 데이터 구조다.

List의 경우 List에서 값을 빼서 Integer를 String으로 변환하는 함수 (나)를 수행하고 다시 주입(다) 를 한다.
자바에서의 Monad는 함수형 프로그래밍의 개념으로 특정 타입의 값을 둘러싸고 이 값을 변형하는 연산을 연쇄적으로 적용할 수 있게 해주는 패턴이다. 복잡한 작업의 흐름을 단순화하고, 에러 처리나 비동기 연산과 같은 고급 기능을 구현하는 데 도움을 준다.
Optional, Stream 등이 Monad 패턴이다.

수학적 함수정의가 아닌 프로그래밍적 함수 정의에서는 Exception이 발생한다. 그래서 순수함수성에 위배가 된다. 그래서 Monad를 사용하여 Integer -> 성공과 실패를 가진 상태포함 값 String 으로 변환한다.
변환 과정에서 처리할 수 있는 에러를 처리하고, 성공 또는 실패의 상태를 명확하게 관리한다.

성공하면 Optional로 String 타입의 값이 들어가고 실패하면 NullPointException이 발생한다.
Optional로 NullPointException이 발생하지 않도록 구조화(null을 감춤)하고 Exception을 하나의 값으로 갖고 있다.
즉 Exception 때문에 성공과 실패가 있는 자료구조를 만든 것.
JS에서 Promise처럼 연쇄적으로 then, catch한 방식을 생각하면 된다.
Lazy Evaluation으로 중간에 끊기지 않게 하는 지연 연산이 가능하다.

Monad를 한 마디로 하면 상태를 가진 값에서 "연산 결과" 상태를 가진 값이 되는 것이다. (Function Composition 가능 = Chaining 가능)
연산 결과 상태를 가진 값은 Optional로 또 Optional하기 때문에 함수 Composition에 문제가 발생한다.(한 번 더 수행을 함.)
이 2번의 Optional이 된 값을 한 꺼풀 벗겨내야 한다. 이 작업이 flatMap 함수다.
🔗 https://blog.naver.com/2feelus/220822702794
🔗 https://inseo24.github.io/etc/monad