 (ns simple-check.generators
   (:require [simple-check.util :as util])
   (:import java.util.Random)
-  (:refer-clojure :exclude [int vector map]))
+  (:refer-clojure :exclude [int vector map keyword char]))
 
 (defn random
   ([] (java.util.Random.))

    (let [num-elements (Math/abs (int rand-seed size))]
      (vec (repeatedly num-elements #(gen rand-seed size))))))

(defn shrink-vector
  [value]
  (clojure.core/map vec (shrink-seq value)))

(defn map
  [key-gen val-gen]
  (fn [rand-seed size]
    (into {} (repeatedly (rand-int size)
                         (fn [] [(util/nullary-apply key-gen)
                                 (util/nullary-apply val-gen)])))))

(defn shrink-map
  [value]
  [])

;; Combinators
;; ---------------------------------------------------------------------------

(defn one-of
  [generators]
  (bind (choose 0 (dec (count generators)))
        #(nth generators %)))

(defn such-that
  [gen f]
  (fn [rand-seed size]
    (let [value (gen rand-seed size)]
      (if (f value)
        value
        (recur rand-seed size)))))

;; Instances
;; ---------------------------------------------------------------------------


(extend clojure.lang.IPersistentMap
  Shrink
  {:shrink shrink-map})
