고급 Haskell 주제를 학습할 때 꼭 읽어야 할 대표 튜토리얼 링크 모음: 모나드, 모나드 변환기, 파싱, 프리 모나드, 코루틴, 렌즈, 교회 인코딩 등을 다룹니다.
Haskell for all: 고급 Haskell 주제 소개
===============
화요일, 2014년 3월 25일
많은 사람들이 Haskell 전문가와 초보자 사이의 큰 격차를 안타까워합니다. 제가 관찰한 바에 따르면, “고급” Haskell 주제들은 공통점이 하나 있습니다. 그 주제에 대한 좋은 튜토리얼이 단 하나만 존재하고, 그걸 찾은 사람만 전문가가 된다는 점입니다. 이 글은 제가 생각하는 각 주제의 결정판 튜토리얼 링크 모음입니다.
모나드는 기술적으로 고급 Haskell 주제는 아니지만, 대부분의 모나드 튜토리얼이 형편없거나 오해를 부른다는 이유로 목록에 포함했습니다. 제 생각에 최고의 모나드 튜토리얼(제목: "You could have invented monads")은 Dan Piponi가 8년 전에 썼고, 그 이후로 이를 능가한 글은 한 번도 보지 못했습니다.
항상 저를 당황하게 하는 것 중 하나는 블로그 영역에서 모나드 변환기 사용법을 설명하는 글이 거의 없다는 점입니다. 사실, 제가 아는 유일한 좋은 설명은 [Martin Grabmuller의 아주 간단한 논문(제목: "Monad Transformers - Step by Step")] (https://page.mi.fu-berlin.de/scravy/realworldhaskell/materialien/monad-transformers-step-by-step.pdf)입니다. 대부분의 초보자는 튜토리얼을 찾을 때 이런 학술 논문을 건너뛰는데, 보통 사람들은 "학술적"이라는 단어에서 친절한 입문서를 떠올리지 않기 때문이죠. 그러나 속지 마세요. 이 논문은 정말 잘 쓰였고 읽기 쉽습니다.
Haskell 밖에서는 모나드가 Haskell의 약점을 덮기 위해 존재한다고 말하는 사람도 있지만, 모나딕 파서를 접하면 그런 생각이 바뀝니다. 진짜로 머리가 번쩍하는 순간은 Hutton과 Meijer의 [모나딕 파싱에 대한 펄(Functional Pearl) 논문(제목: "Monadic Parsing in Haskell")] (http://www.cs.uwyo.edu/~jlc/courses/3015/parser_pearl.pdf)을 읽고, 그것이 얼마나 간단히 구현될 수 있는지를 알게 될 때입니다. 이 글은 백트래킹 파서를 구현하는 법, 그 파서에 대한 Monad 타입 클래스를 구현하는 법, 그리고 여러 파싱 프리미티브를 정의하고 이를 연결해 더 정교한 기능을 만드는 법까지 단계적으로 설명합니다. 이 펄 논문을 읽고 나면 모나드의 중요성을 절대 의심하지 않게 될 것입니다.
파서 콤비네이터를 이해해야 하는 또 다른 이유가 있습니다. Haskell의 파서 콤비네이터 라이브러리는 Haskell의 정규식 라이브러리보다 훨씬 앞서 있습니다. Python이나 Perl처럼 정규식을 많이 쓰는 언어에서 Haskell로 온 사람들은 Haskell의 정규식 지원이 왜 이렇게 나쁜지 의아해합니다. 그 이유는 거의 모든 Haskell 프로그래머가 parsec이나 attoparsec 같은 파서 콤비네이터 라이브러리를 쓰기 때문입니다.
이 부분은 제 글을 하나 홍보하겠습니다. 저는 한때 프리 모나드를 이해하려고 노력했지만 초보자 친화적인 설명을 찾을 수가 없어서 [프리 모나드 튜토리얼(제목: "Why free monads matter")] (http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html)을 썼습니다. 이 주제에 대한 자료는 대부분 수학자를 대상으로 쓰였고, 사용 사례도 수학적 예시로 동기를 부여하곤 했습니다.
저는 프리 모나드의 동기를 프로그래머가 이해할 수 있는 용어로 설명하고 싶었고, 제 글은 구문 트리를 만들고 그 트리를 해석하는 관점에서 이 주제를 다룹니다. 프리 모나드를 이해하면 Haskell 안에서 모나딕 DSL을 구축하는 법에 대한 이해가 크게 향상됩니다. 또한 많은 사람들이 프리 모나드를 이해하면 Haskell의 IO에 대한 정신 모델도 크게 개선된다고 말합니다.
Haskell의 코루틴 라이브러리(pipes/conduit/machines 등)의 내부 구현은 뚫을 수 없을 것처럼 보입니다. ...그러다 Mario Blazevic가 The Monad Reader 19호에서 쓴 [코루틴에 대한 글(제목: "Coroutine Pipelines")] (http://themonadreader.files.wordpress.com/2011/10/issue19.pdf)을 읽기 전까지는요.
그 글에서 그는 모든 코루틴 구현을 하나의 패턴으로 통합하는 Coroutine 타입(요즘은 프리 모나드 변환기로 더 잘 알려져 있습니다)을 소개합니다. 그 글을 이해하고 나면 코루틴 라이브러리의 내부를 이해하게 되고, 직접 스트리밍 라이브러리를 손쉽게 작성할 수 있을 것입니다.
렌즈 튜토리얼은 새로운 모나드 튜토리얼입니다. 그리고 모든 렌즈 튜토리얼이 저지르는 하나의 실수는 렌즈가 "어떻게 작동하는지"를 명확히 설명하지 않는다는 점입니다. 이를 제대로 해낸 유일한 글은 Twan van Laarhoven이 [현대적 렌즈 정식화(제목: "CPS Functional references")] (http://twanvl.nl/blog/haskell/cps-functional-references)를 처음 소개한 원글입니다. 문제는 제목이 생소하고 글 전체에서 "lens"라는 단어가 한 번만 언급되어서, 렌즈 튜토리얼을 찾으려고 구글을 샅샅이 뒤져도 이 글을 찾기 무척 어렵다는 것입니다. 저도 그의 블로그 아카이브를 훑으면서조차 제목을 알아보지 못해 이 글을 찾는 데 애를 먹었습니다.
특별 언급: lens-family-core 라이브러리는 Twan의 원래 발표를 실제로 충실히 따르는 유일한 렌즈 라이브러리이므로, 이해를 더 깊게 하고 싶다면 소스 코드를 꼭 공부해 보시길 권합니다.
아직도 교회 인코딩에 대해 잘 쓴 블로그 글을 찾지 못했으므로 링크는 걸지 않겠습니다. 하지만 한 번 데이터 타입을 교회 인코딩하는 법을 배우고 나면 이 패턴이 온갖 곳에서 눈에 들어올 것입니다.
동일하게 중요한 점은, 많은 고성능 Haskell 라이브러리(예: attoparsec)가 효율을 위해 교회 인코딩을 사용한다는 것입니다. 교회 인코딩을 이해하면 이들 라이브러리의 내부 구현도 이해할 수 있습니다.
이처럼 중요한 Haskell 주제들이 찾기 어려운 단 하나의 진실의 원천만 가지고 있다는 사실이 정말 실망스럽습니다. 제 가설은 Haskell이 컴퓨터 과학 학계에 뿌리를 두고 있고, 같은 주제에 대한 중복 출판을 꺼리는 문화가 문제라는 것입니다. 제가 틀렸다고 증명하고 싶다면, 부디 위와 같은 핵심 주제들에 대해 고품질 Haskell 튜토리얼의 수를 늘리는 데 시간을 써 주세요.
또 다른 우려스러운 추세는 사람들이 섹시한 튜토리얼 주제에 편승하는 경향입니다(처음엔 모나드, 이제는 렌즈). 더 평범한 주제, 즉 이미 잘 자리 잡은 라이브러리를 활용해 다양한 종류의 애플리케이션을 설계하는 방법 같은 내용에 더 많은 시간을 썼으면 합니다.
작성자: Gabriella Gonzalez, 작성 시각: 오전 12:18
이메일로 보내기블로그에 공유X에 공유Facebook에 공유Pinterest에 공유
Anonymous2014년 3월 25일 오전 6:51
"이처럼 중요한 Haskell 주제들이 찾기 어려운 단 하나의 진실의 원천만 가지고 있다는 사실이 정말 실망스럽습니다."동의합니다. 저는 오래전부터 Haskell의 가장 큰 약점은 좋은 책이 많지 않다는 점이라고 생각해 왔습니다. 대부분의 문서는 여기저기 흩어진 논문과 블로그 글에 존재합니다. 심지어 라이브러리 Haddock 문서에도 논문을 참조하는 경우가 많고, 그 중 일부는 찾기도 어렵습니다.
"렌즈 튜토리얼은 새로운 모나드 튜토리얼이다"
이 대목에서 웃었습니다. 저도 한동안 그렇게 생각해 왔거든요. 그래서 렌즈를 피하고 있던 이유이기도 합니다. 렌즈는 여러 개념을 한데 욱여넣은 거대한 잡탕처럼 보입니다.
"사람들이 왜 Haskell의 정규식 지원이 이렇게 나쁜지 궁금해한다"
사실 Haskell의 정규식 지원은 Python만큼이나 괜찮다고 생각합니다. Python과 마찬가지로 Haskell에서도 정규식을 쓰려면 라이브러리를 불러와야 합니다. 다양한 라이브러리가 뒤섞여 있어 혼란스럽긴 합니다(특히 regex-base의 과도한 오버로딩 인터페이스는 초보자에게 도움이 되지 않죠). 하지만 pcre-light는 이해하기 쉽고 pcre 라이브러리의 방대한 문서 덕을 봅니다.
하지만 Haskell의 파서 콤비네이터 라이브러리는 정말 빛납니다. 그래서 저는 보통 정적인 작업에는 정규식을 피합니다(런타임에 사용자가 검색 문자열을 지정하게 하려면 정규식이 편리할 때가 있긴 합니다).
1.  [Gabriella Gonzalez](https://www.blogger.com/profile/01917800488530923694)[2014년 3월 25일 오전 7:21](https://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html?showComment=1395757272077#c169119759553211206)
맞아요, pcre-light가 괜찮고 튜토리얼도 그럭저럭 있다는 점을 감안하면 제 정규식 관련 문구를 바꿔야겠네요. 그 부분을 다시 표현해 보겠습니다.
[답글](javascript:;)
Anonymous2014년 3월 25일 오전 6:51
이 글들이 교회 인코딩 입문으로 꽤 괜찮습니다. 링크할 가치가 있을지도요.http://jozefg.bitbucket.org/posts/2014-03-06-church.html
[답글](javascript:;)
3.
Xav2014년 3월 25일 오후 2:07
렌즈에 관해서는 Simon Peyton Jones의 이 강연이 정말 명확했습니다:
https://skillsmatter.com/skillscasts/4251-lenses-compositional-data-access-and-manipulation
[답글](javascript:;)
4.
Unknown2014년 3월 25일 오후 3:21
정말 멋진 글이에요. FRP 자료도 추천해 주실 게 있나요? FRP도 비슷하게 파편화되어 있는 느낌이라, 이 주제에 대한 추천을 듣고 싶습니다.
1.  [Gabriella Gonzalez](https://www.blogger.com/profile/01917800488530923694)[2014년 3월 25일 오후 9:08](https://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html?showComment=1395806938253#c6872129029850940884)
Elm이 아마 가장 좋은 출발점일 거예요. FRP 분야는 파편화되어 있지만, Evan Czaplicki(Elm의 저자)는 가능한 한 힘을 잃지 않으면서도 단순한 인터페이스를 제공하는 방법에 대해 훨씬 더 많은 고민을 한 것 같습니다.
[답글](javascript:;)
Unknown2014년 3월 26일 오후 12:21
제가 본 것 중 교회 인코딩을 정말 잘 설명한 최고의 글은 이겁니다: http://matt.might.net/articles/compiling-up-to-lambda-calculus/다만 Haskell이 아니라 Scheme의 부분집합으로 설명합니다.
[답글](javascript:;)
6.
goncharenko2014년 3월 31일 오전 1:07
저는 최근에 렌즈에 들어가기 전 읽기 좋은 글 두 편을 찾았습니다. Javrania의 "Implement semantic editor combinators"와 SOH의 "From Zipper to Lens"입니다.
[답글](javascript:;)
7.
wakalabis2014년 11월 30일 오후 2:50
Gabriel, quasi quoting과 Template Haskell에 관한 좋은 튜토리얼은 어디에서 찾을 수 있을까요?
1.  [Gabriella Gonzalez](https://www.blogger.com/profile/01917800488530923694)[2014년 12월 31일 오후 3:08](https://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html?showComment=1420067286083#c5503089484857098036)
Template Haskell을 많이 해 본 것은 아니지만, 이 글이 빠른 소개로 괜찮아 보입니다:
https://www.fpcomplete.com/user/marcin/template-haskell-101
이 페이지에는 Template Haskell 논문과 글에 대한 링크가 많이 모여 있습니다:
https://www.haskell.org/haskellwiki/Template_Haskell
[답글](javascript:;)
polypus742015년 10월 30일 오전 9:26
좋은 자료를 알려줘서 고마워요. 비학술적 관점에서 고급 Haskell을 다루는 책에는 분명히 빈틈이 있다고 봅니다.[답글](javascript:;)
9.
Unknown2016년 6월 18일 오후 3:12
모나드 변환기 링크가 깨졌습니다.
1.  [Gabriella Gonzalez](https://www.blogger.com/profile/01917800488530923694)[2016년 7월 3일 오후 2:45](https://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html?showComment=1467582313023#c6129408124483750697)
알려줘서 고마워요! 링크를 고쳤습니다.
[답글](javascript:;)
2.  [ThoperSought](https://www.blogger.com/profile/10476866865517800695)[2021년 11월 7일 오후 5:34](https://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html?showComment=1636335240936#c9103012045390718498)
제가 모나드 변환기 논문을 찾다가 이 페이지를 보게 되었으니, 제가 찾은 링크도 여기에 함께 남겨둡니다:
https://github.com/mgrabmueller/TransformersStepByStep
스팸이 아니라 도움이 되길 바랍니다.
[답글](javascript:;)