(Functor, Applicative, Monad의 정의)
참고로 Monad가 Applicative를 superclass로 가진다 해서 <*>와 >>=가 orthogonal한(?) 기능을 가진다고 생각하면 안된다.
왜냐면 >>=를 가지고 <*>를 만들 수 있음.
사실 Applicative, Monad 차이는 그냥 둘다 쓰다보면 충분히 느낄 수 있다.
Monad는 한마디로 만능이다. procedural한 언어에서 하는거랑 비슷함.
연산을 실행하고, 그 결과를 가지고 다른 일을 하는 이런 순차적인 작업을 표현할 수 있음.
Applicative를 가지고 할 수 있는건 n인자 함수를 lifting하는 것 뿐임.
fmap하고 <*>만 가지고 n인자 함수 f를 인자로 받는 liftAn 함수를 만들어 낼 수 있다.
liftAn f fx1 fx2 ... fxn = f <$> fx1 <*> fx2 <*> ... <*> fxn(<$>는 fmap의 infix operator 버전임)
<*>가 liftAn보다 훨씬 사용하기 좋음. 근데 Applicative가 뭔지는 liftAn을 봐야 이해가 될거임.
liftAn이 가진 기능은 effect를 가진 여러개의 값들을 순수함수를 사용해서 하나로 결합하는거임.
liftA2랑 >>= 타입을 들여다 보니까 좀 더 깨닫는 바가 있더라.
liftA2는 f가 달린 인자가 f a, f b임.
이건 이게 무슨 effect를 발생시킬지 이미 다 정해져 있다는거임.
잘 모르겠으면 IO Char같은거 생각해보면 됨.
반면 >>=는 a -> m b를 인자로 받음.
이건 a가 뭐가 될지에 따라서 동작이 바뀐다! 이게 제일 결정적인 차이임.
이걸 Parser combinator로 보면 context-sensitive한 문법을 표현할 수 있다고도 이해할 수 있음.
결론: Applicative는 주어진 연산들을 조합하는것만 할 수 있다. Monad는 어떤 연산을 할지를 입력을 받고서 동적으로 결정할 수 있음
ㅊㅊ
하스켈하면 알게되는거냐 아니면 모르는놈은 하스켈을 할수없는거냐
둘다임 ㅋㅋ. 하스켈하면 알게됨. 왜냐면 모나드랑 어플리케이티브 사용법은 모나드랑 어플리케이티브 정의를 공부하다 깨닫는게 아니라 머리좋은 사람들이 쓰는거 보고 따라하는거라고 생각함. 근데 그것도 안되면 하스켈 못하는거지 뭐
러스트 Option 반환하는 함수에서 ? 하는게 do모나드랑 비슷함
하스켈 언어 자체도 재밌고 공부할 거리도 많지만, 확실히 다른 언어 쓰는 스타일에도 영향을 많이 주는것같음
난 하스켈 시작한 이래로 다른 언어를 거의 안해서 ㅋㅋ C 할때 const 왕창 쓰게되긴 함.
그러다 굶어죽어요