Last active
October 25, 2019 18:35
-
-
Save ha2ne2/dc2c08ce212c3c7af372bf8cbbd861b8 to your computer and use it in GitHub Desktop.
Clojureでラムダ計算
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 2019-10-26 | |
;;;; 関数をカリー化して定義します。 | |
;; (defn-c add [a b] (+ a b)) が | |
;; (def add (fn [a] (fn [b] (+ a b)))) になります。 | |
(defmacro defn-c [fn-name args body] | |
`(def ~fn-name (fn-c ~args ~body))) | |
(defmacro fn-c [[x & xs :as args] body] | |
(if (empty? args) | |
body | |
`(fn [~x] | |
(fn-c ~xs ~body)))) | |
(defn-c one [f x] (f x)) | |
(defn-c two [f x] (f (f x))) | |
(defn-c three [f x] (f (f (f x)))) | |
(defn-c add [n m f x] ((n f) ((m f) x))) | |
(defn-c mul [n m f x] ((n (m f)) x)) | |
(defn-c pow [n m f x] (((m n) f) x)) | |
(defn-c dec' [n f x] (((n (fn-c [g h] (h (g f)))) (constantly x)) identity)) | |
(defn decode [n] ((n inc) 0)) | |
(decode ((add one) two)) ;=> 3 | |
(decode ((mul three) two)) ;=> 6 | |
(decode ((pow three) two)) ;=> 9 | |
(decode (dec' ((pow three) two))) ;=> 8 | |
;;;;;;;; 適用の所がちょっとあれなのでマクロを使ってもう一歩進めてみる。 | |
;;;; 式をHaskellみたいな感じに評価します。 | |
;; (<- a b c d) が | |
;; (((a b) c) d) になります。 | |
;; 再帰的に適用するので | |
;; (<- a b c d (e f g)) は | |
;; (((a b) c) d ((e f) g) になります。 | |
(defmacro <- [& lst] | |
`(<-% ~(reverse lst))) | |
(defmacro <-% [[x & xs]] | |
(cond (empty? xs) x | |
(list? x) (list `(<-% ~xs) `(<-% ~(reverse x))) | |
:else (list `(<-% ~xs) x))) | |
(defn-c add [n m f x] (<- n f (m f x))) | |
(defn-c mul [n m f x] (<- n (m f) x)) | |
(defn-c pow [n m f x] (<- m n f x)) | |
(def-c dec' [n f x] | |
(let [hoge (fn-c [g h] (h (g f)))] | |
(<- n hoge (constantly x) identity))) ;; <-が再帰的なのでletしないといけない。びみょう。 | |
(decode (<- add one two)) ;=> 3 | |
(decode (<- mul three two)) ;=> 6 | |
(decode (<- pow three two)) ;=> 9 | |
(decode (<- dec' (pow three two))) ;=> 8 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment