이 혼란하게 한 가지입니다 같은 "인기있는"기능 bind
및<*>
이 실습 중심적 입니다. 그러나 개념을 이해하려면 다른 기능을 먼저 보는 것이 더 쉽습니다. 모나드는 다른 연결된 개념에 비해 약간 과장되어 있기 때문에 눈에 띄는 점이 있습니다. 펑터부터 시작하겠습니다.
펑 터는 기능을 제공합니다 (하스켈 표기법으로) fmap :: (Functor f) => (a -> b) -> f a -> f b
. 다시 말해서 f
함수를 들어 올릴 수 있는 컨텍스트 가 있습니다. 당신이 상상할 수 있듯이 거의 모든 것이 functor입니다. 목록, 어쩌면, 함수, I / O, 튜플, 파서 ... 각각은 값이 나타날 수있는 컨텍스트를 나타냅니다. 따라서 fmap
인라인 변형 을 사용하여 거의 모든 상황에서 작동하는 매우 다양한 기능을 작성할 수 있습니다 <$>
.
컨텍스트와 관련하여 다른 작업을 원하십니까? 두 컨텍스트를 결합 할 수 있습니다. 따라서 다음 zip :: [a] -> [b] -> [(a,b)]
과 같은 일반화를 원할 수 있습니다 .pair :: (Monoidal f) => f a -> f b -> f (a,b)
.
그것은 훨씬 더 유용 실제로 때문에 그러나, 하스켈 대신 제공하는 도서관 Applicative
의 조합이다, Functor
하고 Monoidal
, 또한의 Unit
당신이 실제로 값 "내부"와 컨텍스트를 넣을 수있는 추가하는 unit
.
작업중인 컨텍스트에 대해이 세 가지 사항 만 명시하면 매우 일반적인 함수를 작성할 수 있습니다.
Monad
그 위에 말할 수있는 또 다른 것입니다. 이전에 언급하지 않은 것은 이미 두 가지 컨텍스트를 결합하는 두 가지 방법이 있다는 것입니다. 두 가지 컨텍스트를 결합 pair
할 수있을뿐만 아니라 스택 할 수도 있습니다 (예 : 목록 목록을 가질 수 있음). I / O 컨텍스트에서 예제는 파일에서 다른 I / O 작업을 읽을 수있는 I / O 작업이므로 type이 FilePath -> IO (IO a)
있습니다. 우리는 어떻게 그 스태킹을 제거하여 실행 가능한 함수를 얻을 수 IO a
있습니까? 그것이 Monad
s를 join
들어오는 곳 이며, 같은 유형의 두 가지 컨텍스트를 결합 할 수 있습니다. 파서, 어쩌면 등도 마찬가지입니다 bind
. 더 실용적인 방법입니다.join
따라서 모나드 컨텍스트는 네 가지만 제공하면되며 I / O, 파서, 오류 등을 위해 개발 된 거의 모든 기계와 함께 사용할 수 있습니다.