Skip to content

Instantly share code, notes, and snippets.

@echosa
Last active August 29, 2015 14:04
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/c332c76b4603c44a72d9 to your computer and use it in GitHub Desktop.
Save echosa/c332c76b4603c44a72d9 to your computer and use it in GitHub Desktop.
history command that I can't get to get properly typed
(t/ann ^:no-check history-cmd [t2/Game -> String])
(defn history-cmd
"The history command."
[game]
(str "*** START HISTORY ***"
(w/walk #(str "\n> " (:command %) "\n\n" (:response %) "\n")
#(apply str %)
(if (< (count (:turn-history game)) 4)
(:turn-history game)
(subvec (:turn-history game) (- (count (:turn-history game)) 4))))
"*** END HISTORY ***"))
;; Relevant custom types
(t/defalias Player
"The player."
(t/HMap :mandatory {:name String}))
(t/defalias Turn
"A single player turn including command and response."
(t/HMap :mandatory {:command t/Symbol
:response String}
:optional {:invalid t/Bool}))
(t/defalias Room
"A room in an area of the world."
(t/HMap :mandatory {:name String}))
(t/defalias Biome
"This is just an alias for String, to hold a biome name."
String)
(t/defalias Area
"An area of the world."
(t/HMap :mandatory {:name String
:type Biome}
:optional {:rooms (t/Vec (t/Option Room))
:trees t/Num}))
(t/defalias World
"The world."
(t/HMap :mandatory {:areas (t/Vec Area)}))
(t/defalias Game
"The game."
(t/HMap :mandatory {:player Player
:world World
:turn-history (t/Vec (t/Option Turn))}
:optional {:last-turn Turn}))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 6687.601 msecs"
core.typed initialized.
Start collecting zork-fortress.core
Start collecting zork-fortress.cmds
Start collecting zork-fortress.types
Finished collecting zork-fortress.types
Finished collecting zork-fortress.cmds
Finished collecting zork-fortress.core
Collected 3 namespaces in 1159.468 msecs
Not checking clojure.core.typed (tagged :collect-only in ns metadata)
Start checking zork-fortress.types
Checked zork-fortress.types in 760.991 msecs
Not checking clojure.walk (tagged :collect-only in ns metadata)
Start checking zork-fortress.cmds
Checked zork-fortress.cmds in 1127.613 msecs
Start checking zork-fortress.core
Checked zork-fortress.core in 291.88 msecs
WARNING: Type Checker: Definition missing: clojure.walk/walk
Hint: Use :no-check metadata with ann if this is an unchecked var
Checked 5 namespaces (approx. 2553 lines) in 3379.838 msecs
Type Error (zork_fortress/cmds.clj:17:9) Unannotated var clojure.walk/walk
Hint: Add the annotation for clojure.walk/walk via check-ns or cf
in: w/walk
Type Error (zork_fortress/cmds.clj:18:17) Bad arguments to apply:
Target: (t/IFn [t/Any * -> java.lang.String])
Arguments: t/Any
in: (apply str p1__520#)
Type Checker: Found 2 errors
Found errors
@frenchy64
Copy link

The issue is #(apply str %) defaults to (fn [% :- Any] (apply str %)).

apply needs a sequence as its last argument. Try (fn [a] {:pre [(or (nil? a) (coll? a))]} (apply str a)).

@echosa
Copy link
Author

echosa commented Jul 31, 2014

I get the same error after replacing #(apply str %) with (fn [a] {:pre [(or (nil? a) (coll? a))]} (apply str a)). The only change I see in the output is in: (apply str a) instead of in: (apply str p1__520#).

Additionaly, I would never have figured out the issue was with apply expecting a sequence. How should I have read the output to figure that out? I feel like I'm just missing something.

@echosa
Copy link
Author

echosa commented Jul 31, 2014

This was the solution:

(t/ann clojure.walk/walk [[t/Any -> t/Any] [t/Any -> t/Any] t/Any -> t/Any])
(t/ann history-cmd [t2/Game -> String])
(defn history-cmd
  "The history command."
  [game]
  (str "*** START HISTORY ***"
       (w/walk #(str "\n> " (:command %) "\n\n" (:response %) "\n")
               (fn [a] {:pre [((t/pred (t/U nil (t/Coll t/Any))) a)]} (apply str a))
               (if (< (count (:turn-history game)) 4)
                 (:turn-history game)
                 (subvec (:turn-history game) (- (count (:turn-history game)) 4))))
       "*** END HISTORY ***"))

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