Hi.

I've been experimenting with clojure spec and a game of life problem, and
have been trying to spec a rectangular board of unknown size made up of a
collection of rows, each of which contain an equal number of cells. My
initial attempt was:-

(def cell? #{0 1})

(s/def ::row (s/coll-of cell? :min-count 1))

(s/def ::board (s/& (s/+ ::row)
                    #(apply = (map count %))))


This appears to work, but I'm wondering if there is a better way to specify
the constraint that every row should be the same length? What would be the
recommended way to achieve this?

Following on from this, I then wanted to generate input boards and exercise
a function so I tried the following which give me an ArityException:-

(s/def ::board (s/with-gen
                 (s/& (s/+ ::row)
                      #(apply = (map count %)))
                 #(gen/bind (s/gen pos-int?)
                            (fn [n]
                              (s/gen (s/coll-of (s/coll-of cell? :count n)))))))

(s/fdef my-function :args (s/cat :board ::board))

(defn my-function [board])

(s/exercise (:args (s/get-spec `my-function)) 1)

=> ([([1] [0] [0] [1] [0]) {:board [[1] [0] [0] [1] [0]]}])

(s/exercise-fn `my-function)

=> ArityException Wrong number of args (20) passed to: user/my-function



If I try and do something similar without the custom generator such as:

(s/def ::coll (s/coll-of (s/coll-of int? :count 2)))

(s/fdef my-function2 :args (s/cat :board ::coll))

(defn my-function2 [board])

(s/exercise (:args (s/get-spec `my-function2)) 1)

=> ([(*[*[0 -1] [0 -1] [0 -1]*]*) {:board [[0 -1] [0 -1] [0 -1]]}])

(s/exercise-fn `my-function2)

This all works as expected. I can see that there is an extra level of
nesting here though and this must be where the error is coming from, as
it's applying my-function to the collection rather than using it as a
single argument - but I'm not sure what is causing this difference.

These look the same in terms of structure:

(gen/sample (s/gen ::coll) 1)
=> ([[-1 -1] [-1 0] [0 -1] [-1 -1] [-1 0] [-1 0]])

(gen/sample (s/gen ::board) 1)
=> ([[0 1] [1 1] [1 1] [1 1] [1 1] [0 0] [0 1]])

(s/fdef my-function :args (s/cat :board ::board))

(s/fdef my-function2 :args (s/cat :board ::coll))


But these don't:

(gen/sample (s/gen (:args (s/get-spec `my-function))) 1)
=> (([1 0] [0 0] [0 1] [0 1] [1 1]))
(gen/sample (s/gen (:args (s/get-spec `my-function2))) 1)
=> (([[-1 -1] [-1 -1] [0 0] [0 0] [-1 0] [-1 -1] [0 0]]))


I'm sure it's something obvious, but I been looking for a couple of hours
and can't seem to see it - could someone please help point me in the right
direction.

Thanks in advance.

Jason


-- 
Jason Courcoux

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to