If you're representing a matrix with vectors, then any public function that
operates on a matrix should return vectors.

You may want to consider a function like:

(defn matrix? [m]
  (and (vector? m)
       (every? vector m)
       (apply = (count m) (map count m)))

Then add it as a pre and post condition:

(defn transpose [m]
  {:pre [(matrix? m)] :post [(matrix? %)]}
  (apply mapv vector m))

That'll provide some type guarantees.

- James


On 9 May 2014 00:28, Joseph Rollins <rollins.jos...@gmail.com> wrote:

> I am confused about the best way to assure that I am dealing with a vector
> when dealing with core library functions that often return seq where I then
> lose my ability to access it using associative accesses (get-in
> specifically).
>
> My particular use case is as follows:
>
> I am modeling a matrix as nested vectors
>
> [[0 0 0] [0 1 1] [0 1 1]]
>
> represents
>
> 0 0 0
> 0 1 1
> 0 1 1
>
> I know matrix libraries exist, but for the sake of learning am rolling my
> own functionality.  I have several functions that operate on this:
>
> (defn transpose [piece]
>   (apply mapv vector piece))
>
> (defn translate-block
>   ([mm]   (let [one? #(if (= 1 %) true false)]
>             (translate-block mm one?)))
>   ([mm f] (map #(map f %) mm)))
>
> (defn rotate-left [b]
>   (->> b
>        transpose
>        reverse))
>
> The problem I am running into is that these do not output nested vectors,
> but nested seqs (due to all of the map operations). I am using these
> matrices to program Tetris, and I am writing a function that takes a Tetris
> block, a Tetris board (both represented as matrices) and a position of the
> block inside the board. The function is supposed to determine if the
> placement of the block is valid (not overlapping already placed blocks:
>
> (defn is-valid?
>   "Determine if a game state is valid (is current piece place-able)."
>   [{board :board {:keys [piece pos]} :piece}]
>   (let [[x y] pos
>         coords (for [rows (range (count piece))
>                      cols (range (count (first piece)))]
>                  [[rows cols] [(+ y rows) (+ x cols)]])]
>     (map (fn [[c cc]]
>            (and (get-in board cc) (get-in piece c)))
>          coords)))
>
> The matrices hold true and false values for if occupied. When testing this
> function I realized get-in was just returning nil because it wouldnt get in
> a seq (non-associative).  What is the best way to assure that when I need
> associative guarantees that they haven't been thrown away through previous
> transformations of the board or piece matrices?
>
> The two choices I see are making sure every function that operates on the
> matrices explicitly outputs nested vectors again, or transforming the input
> to functions that need the guarantees to nested vectors explicitly. Am I
> missing something here, or, if not, what is the idiomatic way to solve this
> problem?
>
> Thanks
>
> -Joseph
>
> --
> 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.
>

-- 
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