Mercurial > lasercutter
diff src/clojure/contrib/generic/comparison.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/contrib/generic/comparison.clj Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,214 @@ 1.4 +;; Generic interfaces for comparison operations 1.5 + 1.6 +;; by Konrad Hinsen 1.7 +;; last updated May 25, 2010 1.8 + 1.9 +;; Copyright (c) Konrad Hinsen, 2009-2010. All rights reserved. The use 1.10 +;; and distribution terms for this software are covered by the Eclipse 1.11 +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 1.12 +;; which can be found in the file epl-v10.html at the root of this 1.13 +;; distribution. By using this software in any fashion, you are 1.14 +;; agreeing to be bound by the terms of this license. You must not 1.15 +;; remove this notice, or any other, from this software. 1.16 + 1.17 +(ns 1.18 + ^{:author "Konrad Hinsen" 1.19 + :doc "Generic comparison interface 1.20 + This library defines generic versions of = < > <= >= zero? 1.21 + as multimethods that can be defined for any type. Of the 1.22 + greater/less-than relations, types must minimally implement >."} 1.23 + clojure.contrib.generic.comparison 1.24 + (:refer-clojure :exclude [= < > <= >= zero? pos? neg? min max]) 1.25 + (:use [clojure.contrib.generic 1.26 + :only (root-type nulary-type nary-type nary-dispatch)])) 1.27 + 1.28 +; 1.29 +; zero? pos? neg? 1.30 +; 1.31 +(defmulti zero? 1.32 + "Return true of x is zero." 1.33 + {:arglists '([x])} 1.34 + type) 1.35 + 1.36 +(defmulti pos? 1.37 + "Return true of x is positive." 1.38 + {:arglists '([x])} 1.39 + type) 1.40 + 1.41 +(defmulti neg? 1.42 + "Return true of x is negative." 1.43 + {:arglists '([x])} 1.44 + type) 1.45 + 1.46 +; 1.47 +; Equality 1.48 +; 1.49 +(defmulti = 1.50 + "Return true if all arguments are equal. The minimal implementation for type 1.51 + ::my-type is the binary form with dispatch value [::my-type ::my-type]." 1.52 + {:arglists '([x] [x y] [x y & more])} 1.53 + nary-dispatch) 1.54 + 1.55 +(defmethod = root-type 1.56 + [x] true) 1.57 + 1.58 +(defmethod = nary-type 1.59 + [x y & more] 1.60 + (if (= x y) 1.61 + (if (next more) 1.62 + (recur y (first more) (next more)) 1.63 + (= y (first more))) 1.64 + false)) 1.65 + 1.66 +; 1.67 +; Greater-than 1.68 +; 1.69 +(defmulti > 1.70 + "Return true if each argument is larger than the following ones. 1.71 + The minimal implementation for type ::my-type is the binary form 1.72 + with dispatch value [::my-type ::my-type]." 1.73 + {:arglists '([x] [x y] [x y & more])} 1.74 + nary-dispatch) 1.75 + 1.76 +(defmethod > root-type 1.77 + [x] true) 1.78 + 1.79 +(defmethod > nary-type 1.80 + [x y & more] 1.81 + (if (> x y) 1.82 + (if (next more) 1.83 + (recur y (first more) (next more)) 1.84 + (> y (first more))) 1.85 + false)) 1.86 + 1.87 +; 1.88 +; Less-than defaults to greater-than with arguments inversed 1.89 +; 1.90 +(defmulti < 1.91 + "Return true if each argument is smaller than the following ones. 1.92 + The minimal implementation for type ::my-type is the binary form 1.93 + with dispatch value [::my-type ::my-type]. A default implementation 1.94 + is provided in terms of >." 1.95 + {:arglists '([x] [x y] [x y & more])} 1.96 + nary-dispatch) 1.97 + 1.98 +(defmethod < root-type 1.99 + [x] true) 1.100 + 1.101 +(defmethod < [root-type root-type] 1.102 + [x y] 1.103 + (> y x)) 1.104 + 1.105 +(defmethod < nary-type 1.106 + [x y & more] 1.107 + (if (< x y) 1.108 + (if (next more) 1.109 + (recur y (first more) (next more)) 1.110 + (< y (first more))) 1.111 + false)) 1.112 + 1.113 +; 1.114 +; Greater-or-equal defaults to (complement <) 1.115 +; 1.116 +(defmulti >= 1.117 + "Return true if each argument is larger than or equal to the following 1.118 + ones. The minimal implementation for type ::my-type is the binary form 1.119 + with dispatch value [::my-type ::my-type]. A default implementation 1.120 + is provided in terms of <." 1.121 + {:arglists '([x] [x y] [x y & more])} 1.122 + nary-dispatch) 1.123 + 1.124 +(defmethod >= root-type 1.125 + [x] true) 1.126 + 1.127 +(defmethod >= [root-type root-type] 1.128 + [x y] 1.129 + (not (< x y))) 1.130 + 1.131 +(defmethod >= nary-type 1.132 + [x y & more] 1.133 + (if (>= x y) 1.134 + (if (next more) 1.135 + (recur y (first more) (next more)) 1.136 + (>= y (first more))) 1.137 + false)) 1.138 + 1.139 +; 1.140 +; Less-than defaults to (complement >) 1.141 +; 1.142 +(defmulti <= 1.143 + "Return true if each arguments is smaller than or equal to the following 1.144 + ones. The minimal implementation for type ::my-type is the binary form 1.145 + with dispatch value [::my-type ::my-type]. A default implementation 1.146 + is provided in terms of >." 1.147 + {:arglists '([x] [x y] [x y & more])} 1.148 + nary-dispatch) 1.149 + 1.150 +(defmethod <= root-type 1.151 + [x] true) 1.152 + 1.153 +(defmethod <= [root-type root-type] 1.154 + [x y] 1.155 + (not (> x y))) 1.156 + 1.157 +(defmethod <= nary-type 1.158 + [x y & more] 1.159 + (if (<= x y) 1.160 + (if (next more) 1.161 + (recur y (first more) (next more)) 1.162 + (<= y (first more))) 1.163 + false)) 1.164 + 1.165 +; 1.166 +; Implementations for Clojure's built-in types 1.167 +; 1.168 +(defmethod zero? java.lang.Number 1.169 + [x] 1.170 + (clojure.core/zero? x)) 1.171 + 1.172 +(defmethod pos? java.lang.Number 1.173 + [x] 1.174 + (clojure.core/pos? x)) 1.175 + 1.176 +(defmethod neg? java.lang.Number 1.177 + [x] 1.178 + (clojure.core/neg? x)) 1.179 + 1.180 +(defmethod = [Object Object] 1.181 + [x y] 1.182 + (clojure.core/= x y)) 1.183 + 1.184 +(defmethod > [java.lang.Number java.lang.Number] 1.185 + [x y] 1.186 + (clojure.core/> x y)) 1.187 + 1.188 +(defmethod < [java.lang.Number java.lang.Number] 1.189 + [x y] 1.190 + (clojure.core/< x y)) 1.191 + 1.192 +(defmethod >= [java.lang.Number java.lang.Number] 1.193 + [x y] 1.194 + (clojure.core/>= x y)) 1.195 + 1.196 +(defmethod <= [java.lang.Number java.lang.Number] 1.197 + [x y] 1.198 + (clojure.core/<= x y)) 1.199 + 1.200 +; 1.201 +; Functions defined in terms of the comparison operators 1.202 +; 1.203 +(defn max 1.204 + "Returns the greatest of its arguments. Like clojure.core/max except that 1.205 + is uses generic comparison functions implementable for any data type." 1.206 + ([x] x) 1.207 + ([x y] (if (> x y) x y)) 1.208 + ([x y & more] 1.209 + (reduce max (max x y) more))) 1.210 + 1.211 +(defn min 1.212 + "Returns the least of its arguments. Like clojure.core/min except that 1.213 + is uses generic comparison functions implementable for any data type." 1.214 + ([x] x) 1.215 + ([x y] (if (< x y) x y)) 1.216 + ([x y & more] 1.217 + (reduce min (min x y) more)))