모나드는 부리토와 같다

ko생성일: 2025. 9. 18.

부리토에 빗대어 펑터, map, unit, join과 그 법칙을 유머러스하게 설명하는 모나드 비유 글.

몇 달 전 Brent Yorgey는 모나드를 설명하면서 모나드가 부리토와 같다고 하는 일군의 튜토리얼들에 대해 불평했다. 처음에는 부리토라는 선택이 이 튜토리얼들이 만들어내는 기묘하고 때로는 무리한 비유들을 우스갯소리로 가리키는 것뿐이라고 생각했다. 그러나 곧 모나드가 정말로 부리토와 같다는 것을 깨달았다. 설명하겠다.

모나드는 특수한 종류의 펑터(functor)다. 펑터 F 는 각 타입 T 를 받아 새로운 타입 FT 로 대응시킨다. 부리토는 펑터와 같다. 고기나 콩 같은 타입을 받아 소고기 부리토나 콩 부리토 같은 새로운 타입으로 바꾼다.

펑터에는 또한 map 함수가 갖추어져 있어야 하는데, 이는 원래 타입 위의 함수를 새로운 타입 위의 함수로 들어올려(lift) 준다. 예를 들어, 잘게 썬 할라페뇨나 채 썬 치즈를 어떤 타입(고기나 콩)에든 추가할 수 있다. 이 함수의 들어올린 버전은 해당 부리토에 잘게 썬 할라페뇨나 채 썬 치즈를 추가한다.

모나드에는 또한 unit 함수가 있어야 하는데, 이는 특정한 한 덩어리의 고기처럼 평범한 값을 받아 부리토로 바꿔 준다. 부리토의 unit 함수는 분명히 또르티야다.

마지막으로, 모나드에는 join 함수가 있어야 하는데, 이는 우스꽝스러운 ‘부리토들의 부리토’를 평범한 부리토로 바꿔 준다. 여기서 명백한 join 함수는 겉의 또르티야를 벗겨 내고, 안쪽의 부리토들을 풀어 속 재료를 바깥 또르티야로 옮긴 다음, 안쪽 포장들은 버리는 것이다.

map, join, unit 함수는 어떤 법칙들을 만족해야 한다. 예를 들어, B 가 이미 부리토이고 단지 부리토 속 재료가 아니라면, join(unit(B)) 은 B 와 같아야 한다. 즉, 부리토가 하나 있는데 그걸 또 하나의 또르티야로 감싼 뒤, 내용을 바깥 또르티야로 옮겨 담아 풀어놓으면, 처음 시작한 것과 같은 결과가 나와야 한다는 뜻이다. 이것이 참인 이유는 또르티야들이 서로 구별되지 않기 때문이다. 어떤 또르티야는 예수의 얼굴이 있다고 당신이 지적할 거라는 건 안다. 하지만 그런 것들은 구워져 있어서 부리토 만들기에는 부적합하므로, 여기서는 신경 쓰지 않는다.

그래서 모나드는 정말로 부리토와 같다. 나는 Brent에게, 처음에 그가 부리토로 모나드를 설명하는 튜토리얼 아이디어를 제시했을 때 실제로 염두에 둔 것이 이것이었는지, 그리고 다른 모두가 이것을 곧바로 이해했는지 물었다. 하지만 그는 아니라고 했고, 천재는 나 혼자였다고 했다.

[ 추가 20120106: Chris Done이 이 이론을 만화 형태로 제시했다. ]

[ 추가 20201025: Eugenia Cheng이 이 페이지를 트윗했다! 그런데 마지막 단어 “stupid”의 철자가 설명할 수 없게도 틀려 있다. ]

[/prog 카테고리의 다른 글] 영구 링크