첫번째 하스켈 프로그래밍 스터디 계획


펜실베이나 대학(Univ. of Pennsylvania)의 스테파니 웨어릭(Stephanie Weirich) 교수의 CIS 552 고급 프로그래밍 강의 자료를 가지고 하스켈 프로그래밍 스터디를 진행한다.


목차


  1. 소개
  2. 리스트와 퍼스트 클래스 함수
  3. 고차원 프로그래밍 패턴
  4. 타입 클래스
  5. 모나드 소개
  6. 상태 모나드
  7. 임의의 모나드와 입출력
  8. 모나드를 사용한 파싱 [1,2]
  9. 퀵체크(QuickCheck) [1,2]
  10. 모나드 변환
  11. 동시성을 제공하는 모나드 [1,2]
  12. 순수 함수 자료 구조
  13. 일반화된 엘지브레익 데이터타입(Generalized Algebraic Datatypes)
  14. 타입을 유지하는 추상 구문
  15. 타입 리플렉션(Type Reflection) [1,2]

참고 강의 사이트
  • http://www.seas.upenn.edu/~cis552/11fa/schedule.html



Posted by lazyswamp :

하스켈 프로그래밍(Haskell) 커뮤니티를 시작하며.


1994년 대학원에 들어가서 처음 함수형 프로그래밍 언어 하스켈(Haskell, www.haskell.org)을 접하고 여러 잡다한 프로그래밍을 통해 그 이상한 매력에 끌리게 되었다. 마치 결벽증 환자처럼 "순수함"을 유지하려고 애쓰는 모습도 희한했고, 그러면서도 남들이 하는 일을, 똑같이, 조금 과장해서 말하자면, 더 잘 할 수 있는 것도 멋있었다. 그 매력에 끌려 한때는 모든 다른 프로그래밍 언어는 삼류고, 다 필요없고, 오직 하스켈만 절대 지존이고 유일한 프로그래밍 언어라고 생각했던 적도 있었다. 물론 착각이고. 


20년이 지난 오늘 주변에서 하스켈에 대해 관심있는 사람들이 몇몇 있다. 아직은 학교에 있는 학생들이 대부분인 것 같고 L모 회사에 근무하는 사람도 관심을 가지고 있더라. 그리고 몇 주 전에 참가한 어느 세미나에서 "모나드(Monad)"에 대한 설명을 듣는데 개인적으로 너무 마음에 들지 않았다. 하스켈의 악명 높은 주제이긴 하지만 다른 식으로 얘기할 수 있지 않았을까 생각했다. 하스켈이 유일 무이한 프로그래밍 언어는 아니라는 것을 잘 알고 있지만, "순수함"을 잃지 않으려는 이 대범한 노력을 누가 또 할 수 있을까 생각할 때마다 하스켈 프로그래밍을 하던 학생 시절에 그랬던 것 처럼 가슴이 뛰기도 한다. 그리고 "순수함"을 유지하는 하스켈에 "순수함"을 잃어버린 다른 프로그래밍 언어들이 지향해야하는 모습이 담겨 있다는 생각까지 하게 되면, 하스켈 프로그래밍을 배우는 것은 단지 하스켈 언어만을 배우는 것이 아니라는 생각이 강하게 든다.


이러한 생각을 하다보니 하스켈 프로그래밍 커뮤니티가 하나쯤은 있어도 되겠다는 생각이 문득 들었다. 먼저, 하스켈에서 배운대로, 특별한 개발 목적이 있어서가 아니라 그냥 재미삼아 하스켈 언어를 배우는 스터디 모임을 가지고 커뮤니티를 시작해보려 한다. 이 커뮤니티가 활성화되면 하스켈에 적용된 최신 프로그래밍언어 기술에 대해서 논의하고, 나아가서 상용 목적으로 하스켈을 응용하는 사례에 대해 살펴보는 장으로 발전하기를 기대해본다.


2015/8/31


K. Choi


Posted by lazyswamp :

아담 칠리파라(Adam Chlipala)의 책 9.2절 Heterogeneous Lists 참고. 


ML이나 Haskell에서 리스트는 매우 빈번하게 사용한다. [1,2,3,4,5]는 1부터 5까지 정수를 포함하는 리스트로 그 타입은 Haskell에서 [Int]이다. ML이나 Haskell에서의 리스트는 타입이 동일한 원소들의 리스트를 얘기한다. 따라서, [1, true]와 같은 식은 허용하지 않는다. Haskell에서 타입 클래스(type class)를 사용하면 타입이 다른 원소들의 리스트를 표현할 수는 있지만 복잡하다. 콕 시스템은 ML이나 Haskell보다 더 복잡한 타입 시스템을 갖추고 있어 상대적으로 간단하게 이러한 리스트를 표현할 수 있다.


콕 시스템에서 타입이 다른 원소들의 리스트를 만드는 방법을 살펴본다. 기본적인 아이디어는 리스트 타입을 타입 수준의 리스트로 색인을 달아 각 원소의 타입이 무엇인지 설명하는 것이다. 간단한 생각이지만 콕으로 표현했을때 간단한 리스트도 꽤 복잡해진다. 


Inductive hlist (A:Type) (B:A ->Type) : list A -> Type :=

   HNil : hlist A B nil

| HCons : forall (x:A) (ls:list A), B x -> hlist A B ls -> hlist A B (x::ls).


예를 들어 hlist의 쓰임새를 살펴보자. 먼저, HCons의 타입은 선언된 바와 같다. 전칭 한정 변수가 네 개이다.


Check HCons.


HCons

     : forall (A : Type) (B : A -> Type) (x : A) (ls : list A),

       B x -> hlist A B ls -> hlist A B (x :: ls)



첫번째 전칭 한정 변수 A를 Set으로 대체한다. 


Check HCons Set.


HCons Set

     : forall (B : Set -> Type) (x : Set) (ls : list Set),

       B x -> hlist Set B ls -> hlist Set B (x :: ls)


두번째 전칭 한정 변수 B를 (fun T: Set => T)로 대체한다. 사실 이 함수는 Set -> Set 타입을 갖는다. 서브 타입 관계에 의해 Set -> Type으로 간주한다. 


Check HCons Set (fun T:Set => T).


HCons Set (fun T : Set => T)

     : forall (x : Set) (ls : list Set),

       (fun T : Set => T) x ->

       hlist Set (fun T : Set => T) ls ->

       hlist Set (fun T : Set => T) (x :: ls)


그 다음 전칭 한정 변수 x에 bool을 넘긴다. bool의 타입은 Set이다.


Check HCons Set (fun T:Set => T) bool.


HCons Set (fun T : Set => T) bool

     : forall ls : list Set,

       (fun T : Set => T) bool ->

       hlist Set (fun T : Set => T) ls ->

       hlist Set (fun T : Set => T) (bool :: ls)


마지막 전칭 한정 변수 ls에 nil을 준다. nil은 list Set 타입이므로 타입 리스트이다.


Check HCons Set (fun T:Set => T) bool nil.


HCons Set (fun T : Set => T) bool nil

     : (fun T : Set => T) bool ->

       hlist Set (fun T : Set => T) nil ->

       hlist Set (fun T : Set => T) (bool :: nil)


(fun T : Set => T) bool을 베타 환원(beta redunction)으로 계산하면 bool이 된다. 따라서 HCons Set (fun T : Set => T) bool nil의 타입은 bool -> ... 형태이다. 그래서 이 함수의 부울 인자로 true를 지정한다.


Check HCons Set (fun T:Set => T) bool nil true.


HCons Set (fun T : Set => T) bool nil true

     : hlist Set (fun T : Set => T) nil ->

       hlist Set (fun T : Set => T) (bool :: nil)


HNil Set (fun T : Set => T)는 hlist의 정의에 의해 hlist Set (fun T : Set => T) nil 타입을 갖는다.


Check HNil Set (fun T : Set => T)


HNil Set (fun T : Set => T)

     : hlist Set (fun T : Set => T) nil


다시 원래 식으로 돌아가서 마지막 인자로 HNil Set (fun T : Set => T)를 넘기면 hlist 타입의 타입이 다른 원소들의 리스트가 된다.


Check HCons Set (fun T:Set => T) bool nil true (HNil Set (fun T:Set => T)).


HCons Set (fun T : Set => T) bool nil true (HNil Set (fun T : Set => T))

     : hlist Set (fun T : Set => T) (bool :: nil)


조금 간단하게 hlist를 사용하기 위해 다음 세 가지 정의를 도입하자.


Definition HList := hlist Set (fun T:Set => T).

Definition hcons := HCons Set (fun T:Set => T).

Definition hnil := HNil Set (fun T:Set => T).


list Set은 타입 리스트로, 타입이 다른 원소들의 리스트를 표현하는 아이디어가 HList의 타입에 그대로 표현되어 있다. 


Check HList.


HList

      : list Set -> Type


리스트 [1, true]를 다음과 같이 작성할 수 있다.


Check hcons nat (bool::nil) 1 (hcons bool nil true hnil).


hcons nat (bool :: nil) 1 (hcons bool nil true hnil)

     : hlist Set (fun T : Set => T) (nat :: bool :: nil)




Posted by lazyswamp :