Last active
August 29, 2015 14:04
-
-
Save echosa/c332c76b4603c44a72d9 to your computer and use it in GitHub Desktop.
history command that I can't get to get properly typed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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})) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
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.
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
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))
.