Church 数を書いてみた
Emacs Lisp で書いてみる.
とりあえず,Hello World から.
; -*- mode: emacs-lisp; coding: utf-8-unix; -*- ; hello.el (princ "Hello, world!\n")
$ emacs -script hello.el $ emacs -batch -l hello.el # for emacs 21 or before
ちょっと調べたら,lexcal-let*1 を使わないとアレみたい.
d:id:Ehren:20091019:1255976209 さんのを真似して,テストも書いてみる.
;; -*- mode: emacs-lisp; coding: utf-8-unix; -*- ;; church.el (require 'cl) (setq zero ;; church number (lambda (f) (lexical-let ((f f)) (lambda (x) (lexical-let ((x x)) x))))) (setq add1 ;; church number - (+ 1 x) (lambda (n) (lexical-let ((n n)) (lambda (f) (lexical-let ((f f)) (lambda (x) (lexical-let ((x x)) (funcall f (funcall (funcall n f) x))))))))) (setq plus ;; church number - (+ x y) (lambda (m n) (lexical-let ((m m) (n n)) (lambda (f) (lexical-let ((f f)) (lambda (x) (lexical-let ((x x)) (funcall (funcall m f) (funcall (funcall n f) x))))))))) (setq church-to-int (lambda (n) (lexical-let ((n n) (inc (lambda (n) (lexical-let ((n n)) (+ n 1))))) (funcall (funcall n inc) 0)))) (setq print-church (lambda (n) (lexical-let ((n n)) (princ (concat (int-to-string (funcall church-to-int n)) "\n"))))) ;; (let* ((one ;; (funcall add1 zero)) ;; (two ;; (funcall add1 one))) ;; (funcall print-church zero) ;; (funcall print-church one) ;; (funcall print-church two) ;; (funcall print-church (funcall plus one two)) ; (+ 1 2) => 3 ;; (funcall print-church (funcall plus (funcall plus one two) two)) ; (+ (+ 1 2) 2) => 5 ;; ) (provide 'church)
;; -*- mode: emacs-lisp; coding: utf-8-unix; -*- ;; test-church.el (require 'el-expectations) (require 'church) (setq one (funcall add1 zero)) (setq two (funcall add1 one)) (setq three (funcall plus one two)) ; (+ 1 2) => 3 (setq five (funcall plus (funcall plus one two) two)) ; (+ (+ 1 2) 2) => 5 (expectations (desc "zero") (expect 0 (funcall church-to-int zero)) (desc "one") (expect 1 (funcall church-to-int one)) (desc "two") (expect 2 (funcall church-to-int two)) (desc "three") (expect 3 (funcall church-to-int three)) (desc "five") (expect 5 (funcall church-to-int five)) )
$ emacs-app -q --no-site-file --batch -L . -l el-expectations -f batch-expectations aaa test-church.el; cat aaa Executing expectations in nil... 5 expectations, 0 failures, 0 errors Expectations finished at Sun Nov 8 16:35:33 2009 1 :+++++ New expectations +++++ 2 :zero 3 :OK 4 :one 5 :OK 6 :two 7 :OK 8 :three 9 :OK 10 :five 11 :OK 5 expectations, 0 failures, 0 errors Expectations finished at Sun Nov 8 16:35:33 2009
ちょっとfuncall がウザイけど.まぁ.読めばわかるよね.
スコープを作るところに lexcal-let が入っているだけ.
churcl.el のコメントアウトしてある部分を使えば,
emacs -script church.el で確認することもできます.
これで,みんなも Emacs-Lisp でスクリプトが書けるようになったよね.
追記
後から思ったけど,Emacs-Lisp 的には prefix 付けるべきだよな.
最初 lexical-let で囲んでたからそのまま書いちゃった.
参考