我正在製作一個tic tac toe遊戲,併爲我的策略制定了一個協議。遊戲運行良好,所以我想借此機會磨練我的核心技能。我已經詮釋了協議(如下圖所示),但是當我在REPL運行(cf method-name)
或(cf protocol-name)
,我得到這個錯誤:如何在Clojure的core.typed中註釋協議及其方法?
如:
=> `(cf win)`
clojure.lang.ExceptionInfo: Type Checker: Found 1 error :: {:type-error :top-level-error, :errors (#<ExceptionInfo clojure.lang.ExceptionInfo: Unannotated var tic-tac-toe.protocol/win
Hint: Add the annotation for tic-tac-toe.protocol/win via check-ns or cf {:env {:file "/Users/jessediaz/Documents/workspace/tic-tac-toe/src/tic_tac_toe/protocol.clj", :column 5, :line 47}, :form win, :type-error :clojure.core.typed.errors/tc-error-parent}>)}
我已經檢查,以確保版本協議實際上是core.typed /協議。當我使用協議時,控制檯向我咆哮>說該語法已被棄用。我也瀏覽了github頁面和clojure-doc.org上的文檔。這是我學會了如何使用可選的:methods
關鍵字將方法映射到類型。我覺得這可能會從我的代碼中刪除很多重複,但我一直無法找到任何使用它的例子。協議中的主要策略方法都有副作用並返回nil
。驗證方法要麼返回nil
,要麼返回它們驗證的原始方法Strategy
。我不確定我的語法是否正確,但是代碼在LightTable中的評估是否正確,有沒有Fn
簽名,而且它們是core.typed wiki意味着它並不總是必需的。
我覺得我在這裏學習這個驚人的圖書館,並希望任何有洞察力的建議,可以幫助我的理解。
protocol.clj文件:
(ns tic-tac-toe.protocol
(:require [clojure.core.typed :refer :all]))
(ann-protocol Strategy
win (Fn [Strategy -> nil])
block (Fn [Strategy -> nil])
fork (Fn [Strategy -> nil])
block-fork (Fn [Strategy -> nil])
take-center (Fn [Strategy -> nil])
take-opposite-corner (Fn [Strategy -> nil])
take-corner (Fn [Strategy -> nil])
take-side (Fn [Strategy -> nil])
can-win? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-block? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-fork? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-block-fork? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-center? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-corner? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-side? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))]))
(defprotocol Strategy
"Strategy methods update the Tic-tac-toe board when they are called"
;; strategies
(win [_] "wins the game by filling an open space to get 3 in a row")
(block [_] "blocks an opponents win by filling an open space")
(fork [_] "creates a two way win scenario guaranteeing victory")
(block-fork [_] "prevents an opponent from forking")
(take-center [_] "takes center")
(take-opposite-corner [_] "takes a corner opposite to one the computer already has")
(take-corner [_] "takes an avaiable corner")
(take-side [_] "takes an available side")
;; tests
(can-win? [_])
(can-block? [_])
(can-fork? [_])
(can-block-fork? [_])
(can-take-center? [_])
(can-take-opposite-corner? [_])
(can-take-corner? [_])
(can-take-side? [_]))
感謝安布羅斯!我會給這個鏡頭。 – kurofune 2014-12-08 00:53:18
推斷這些方法的輸入類型嗎? – kurofune 2014-12-08 01:06:10
「自我」類型被推斷,並且不能在defprotocol中直接覆蓋(還!)。對於非多態協議,「自我」是策略,否則就是(策略a b c),假設協議由a,b和c參數化。 – Ambrose 2014-12-08 01:41:02