(require '[clojure.spec.alpha :as s]) (s/valid? string? "Hello") (s/valid? string? 42) (s/valid? number? 42) (s/valid? integer? 123) (s/valid? double? 123.45) (s/valid? double? 123) (s/valid? vector? [1 2 3]) (s/valid? map? { 1 "one" 2 "two"}) (s/valid? set? #{:apple :orange}) (s/valid? keyword? :ubuntu) (def valid-%? (s/and number? #(>= % 0) #(<= % 100))) (s/valid? valid-%? 85) (s/valid? valid-%? 105) (s/valid? valid-%? -15) ;; specing collection (def string-collection? (s/coll-of string?)) (s/valid? string-collection? ["Hi" "Hello"]) (def number-or-string? (s/or :number number? :string string?)) (s/valid? number-or-string? 1) (s/valid? number-or-string? "Hi") (def number-or-string-collection? (s/coll-of number-or-string?)) (s/valid? number-or-string-collection? [1 "Hi" "India" 42]) (s/valid? number-or-string-collection? [1 "Hi" "India" 42 :keyword]) ;; inspecting collections (def valid-person-vector? (s/cat :name string? :age number? :gender keyword?)) (s/valid? valid-person-vector? ["Karthik" 40 :male]) (def valid-person-map? (s/keys :req-un [::name ::age ::gender])) (s/valid? valid-person-map? {:name "Karthik" :age 40 :gender :male}) ;; checking maps (s/def ::name string?) (s/def ::age int?) (s/def ::gender keyword?) (s/def ::person (s/keys :req-un [::name ::age ::gender])) (s/valid? ::person {:name "Karthik" :age 40 :gender :male}) (s/valid? ::person {:name "Karthik" :age "40" :gender :male}) ;; explaining spec (s/explain number? "42") (s/explain number? 42) (s/explain number-or-string? "56") (s/explain number-or-string? :56) (s/explain number-or-string? 56) (s/conform number? 42) (s/conform number? "42") (s/conform number-or-string? :56) ;; using spec in functions (defn add-two-numbers [a b] {:pre [(s/valid? number? a) (s/valid? number? b)]} (+ a b)) (add-two-numbers 3 5) (add-two-numbers 3 "5")