Skip to content

Instantly share code, notes, and snippets.

@echosa
Created March 5, 2014 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save echosa/9358930 to your computer and use it in GitHub Desktop.
Save echosa/9358930 to your computer and use it in GitHub Desktop.
An issue I'm having with typed Clojure
(ns greed.coords
(:require [clojure.core.typed :refer [ann]]))
(ann get-next-coordinate-northeast
[NonEmptySeqable (Option Number) (Option Number) -> (Option (IPersistentList Number))])
(defn get-next-coordinate-northeast [grid x y]
(when-not (or (nil? x) (nil? grid) (>= x (- (count (first grid)) 1))
(nil? y) (<= y 0))
(list (+ x 1) (- y 1))))
;; greed.coords> (clojure.core.typed/check-ns)
;; Start collecting greed.coords
;; Finished collecting greed.coords
;; Collected 1 namespaces in 22.57 msecs
;; Start checking greed.coords
;; Checked greed.coords in 237.739 msecs
;; Checked 1 namespaces (approx. 72 lines) in 260.809 msecs
;; Type Error (greed/coords.clj:22:54) Polymorphic function clojure.core/first could not be applied to arguments:
;; Polymorphic Variables:
;; x
;;
;; Domains:
;; (HVec [x Any *])
;; (Option (EmptySeqable x))
;; (NonEmptySeqable x)
;; (Option (clojure.lang.Seqable x))
;;
;; Arguments:
;; clojure.core.typed/NonEmptySeqable
;;
;; Ranges:
;; x
;; nil
;; x
;; (Option x)
;;
;; in: (clojure.core/first grid)
;; in: (clojure.lang.Numbers/gte x (clojure.lang.Numbers/minus (clojure.lang.RT/count (clojure.core/first grid)) 1))
;;
;;
;; ExceptionInfo Type Checker: Found 1 error clojure.core/ex-info (core.clj:4327)
@krisajenkins
Copy link

Sorry, yes - ignore the <= comment!

I had a look, and List* is available, so:

(ann get-next-coordinate-northeast
     [(NonEmptySeqable (NonEmptySeqable Any)) (Option Number) (Option Number)
      ->
      (Option (List* Number Number))])

FWIW, I can't resist playing while I've got 10 minutes. I'd approach from this angle:

(defn- validate
  [grid [x y :as coords]]
  (when (and grid x y
             (<= 0 x (dec (count (first grid))))
             (<= 0 y (dec (count grid))))
    coords))

(def compass {:north [0 -1]
              :east [1 0]
              :south [0 1]
              :northeast [1 -1]
              ...
              })

(defn offset
  [coords direction]
  (map + coords (compass direction)))

(validate grid (offset [2 5] :east))

(Thoroughly untested..)

@echosa
Copy link
Author

echosa commented Mar 5, 2014

Hm. I'll have to investigate this compass idea. Thanks for that. I've been wanting to get a code review, but just haven't asked for one yet. This has been enlightening. Feel free to keep info coming (via any means of communication). :-)

@frenchy64
Copy link

Heterogeneous vectors are much better supported than heterogeneous lists or seqs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment