CLで集合論のおもちゃライブラリを書いたので、これを試してみることに抵抗できませんでした。http://repo.or.cz/w/flub.git/blob/HEAD:/bachelor-cs/set-theory.lispを参照してください。
(use-package '(:alexandria :bachelor-cs.set-theory))
(defun triangles (h)
(let ((range (iota h :start 1)))
(∩ (× (× range range) range)
(lambda (triangle)
(destructuring-bind ((a b) c) triangle
(>= c b a))))))
(defun perimeter (n)
(lambda (triangle)
(destructuring-bind ((a b) c) triangle
(= n (+ a b c)))))
(defun right-triangles (triangle)
(destructuring-bind ((a b) c) triangle
(= (* c c) (+ (* a a) (* b b)))))
(∩ (∩ (triangles 10) (perimeter 24)) #'right-triangles) ↦ (((6 8) 10))
これの見苦しい点は、集合演算がバイナリとして定義されているため、三角形が '((ab) c) として表現されていることです。そうそう、解決すべき素敵ななぞなぞを手に入れました: 変数パラメーター リストの集合操作を定義します。
乾杯、マックス
EDIT:集合演算をn-aryにしました。これで、次のように記述できます。
(∩ (× (iota 10 :start 1) (iota 10 :start 1) (iota 10 :start 1))
(lambda (tri)
(destructuring-bind (a b c) tri
(>= c b a)))
(lambda (tri)
(destructuring-bind (a b c) tri
(= 24 (+ a b c))))
(lambda (tri)
(destructuring-bind (a b c) tri
(= (+ (* a a) (* b b)) (* c c)))))
簡単なマクロを追加する場合 →</p>
(defmacro → (args &rest body)
(let ((g!element (gensym "element")))
`(lambda (,g!element)
(destructuring-bind ,args ,g!element
,@body))))
あなたは読みやすさの点でHaskellバージョンにかなり近づいています:
(∩ (× (iota 10 :start 1) (iota 10 :start 1) (iota 10 :start 1))
(→ (a b c) (>= c b a))
(→ (a b c) (= 24 (+ a b c)))
(→ (a b c) (= (+ (* a a) (* b b)) (* c c))))