clojure.contrib.types

型定義とパターンマッチが使えるライブラリ。
MLっぽいことができる。

(ns calc
  (:refer-clojure :exclude (deftype))
  (:use [clojure.contrib.types :only (deftype defadt match)]))

(defadt ::weekday
  Sunday
  Monday
  Tuesday
  Wednesday
  Thursday
  Friday
  Saturday)

(defn nextday [d]
  (match d
         Sunday    Monday
         Monday    Tuesday
         Tuesday   Wednesday
         Wednesday Thursday
         Thursday  Friday
         Friday    Saturday
         Saturday  Sunday))

(defadt ::expression
  (Numeral value)
  (Plus expr1 expr2)
  (Minus expr1 expr2)
  (Times expr1 expr2)
  (Divide expr1 expr2)
  (Negate expr))

(defn calc [expr]
  (match expr
         (Numeral v) v
         (Plus a b) (+ (calc a) (calc b))
         (Minus a b) (- (calc a) (calc b))
         (Times a b) (* (calc a) (calc b))
         (Divide a b) (/ (calc a) (calc b))
         (Negate a) (- a)))

(comment
  (calc (Plus (Numeral 3)
              (Minus (Numeral 5)
                     (Times (Numeral 2) (Numeral 1))))))