haskell 학습자는 모나드라걸 알아야한다. 이는 설명이 쉽지않고 많은 사람들이 haskell을 포기하게 만드는 요인중 하나이고 아마도 가장 대표적인 원인일 것이다. 그러나 모나드 개념은 다른 언어에서 다 도입해서 사용하고 있다. map, filter 함수처럼 이미 잘 포장된 형식이지만 그 속은 모나드의 패턴이다. 당연히 map함수를 이해하기 위해 모나드까지 공부할 필요는 없다. 다만 그런 함수들을 이해하기 위해 한번쯤 도구를 직접 만들어본다는 개념으로 haskell 모나드를 이해하면 되겠다.
코드 출처:
Maybe 모나드의 return과 >>=의 정의이며 그 자체로 코드가 된다.
eturn :: a -> Maybe a
return x = Just x
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
(>>=) m g = case m of
Nothing -> Nothing
Just x -> g x
>>= 는 bind 연산자로 통상 호칭하면서 그 자체로 함수다.
haskell의 함수는 먼저 타입을 명시해주고 그 아래서 구현해야 한다.
정의되어 있으나 새로 만들수도 있다.
실제 매개변수 역할을 하는 m 과 g 는 실제 사용에서는 함수이나 위 코드에서는 한 값을 그대로 전달하는 역할만 한다. m 에 뭔가 있다면 Just x로 g의 매개변수로 전달한다. 그 x는 m의 반환값인데 별개의 매개변수늘 주는 이유는 Just x -> g x 자체가 별개의 임시함수이기 때문이다. -> 기호는 자바스크립트에서 화살표 함수에 해당한다. 앞은 매개변수이며 뒤에는 함수의 구현 블록이 된다. 연쇄적으로 사용한다면 앞 함수의 반환값이 뒷 함수의 파라미터로 순차적으로 들어간다.
위에 타입에 관하여 Maybe a 에서 a라는 매개변수 타입을 꺼내서 Maybe b 로 전달한다는 의미가 있다. m은 x라는 매개변수로 g x 라는 새로운 Maybe b에 전달되는 것이다.
getTaxOwed :: String -- 이름
-> Maybe Double -- 지불할 세금의 양
getTaxOwed name =
lookup name phonebook >>=
(\number -> lookup number governmentDatabase) >>=
(\registration -> lookup registration taxDatabase)
\ 기호는 리스프의 람다에 해당한다.
이름을 받아 3연속 바인딩을 하는 것을 해당 함수의 구현으로 하고 있다.
처음 연쇄가 첫번째 임시함수에 바인드되어 매개변수로 들어가고 그다음 연쇄가 이전 임시함수를 매개변수를 받는식으로 연쇄가 이어지게 된다. lookup이 바인딩되고 number가 키역할을 하여 데이터베이스에서 조회하게 된다. 그 number는 앞에 바인딩 된 함수의 반환값에 있을것이다. 또한 다음 registration은 앞 함수의 반환값에 있을것이고 lookup 바인딩의 매개변수가 되어 데이터베이스를 조회하게 된다.
이렇게 한다면 정의된 해당 함수 getTaxOwed는 외부에서 키 값과 대조하지 않고 구현된 함수 자체에서 매개변수를 넘겨 새로운 키와 값을 찾는 기능을 포함하게 되는 것이다.(그냥 안에 다 집어넣었다는 뜻 아닌가? 참고로 모나드는 일종의 코드 디자인 패턴이다.)
lookup 함수나 phonebook 구현이 어떻게 되어있는지는 위의 출처에서 확인하기 바란다. 그것만으로는 도저히 이해가 안됨을 알수있을 것이다. 뒤에 데이터베이스는 데이터베이스가 있겠거니 하고 추측만 할 수밖에 없다. 이런 열악한 교재들이 haskell 공부를 더 어렵게 한다. 외국자료중에서 외할아버지 찾기도 분석해보길 바란다.(아마 쉽게 찾을수 있을겁니다)