2014-12-08 49 views
1

我正在製作一個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? [_])) 

回答

2

我懷疑你需要cf查詢它之前check-ns當前的命名空間。類型化代碼的評估不會觸發類型檢查或註釋集合。

這裏不需要ann-protocolclojure.core.typed/defprotocol支持內聯註釋。

試着這麼做:

(defprotocol Strategy 
    "Strategy methods update the Tic-tac-toe board when they are called" 

    ;; strategies 
    (win [_] :- nil "wins the game by filling an open space to get 3 in a row") 
    (block [_] :- nil "blocks an opponents win by filling an open space") 
    ...) 
+0

感謝安布羅斯!我會給這個鏡頭。 – kurofune 2014-12-08 00:53:18

+0

推斷這些方法的輸入類型嗎? – kurofune 2014-12-08 01:06:10

+0

「自我」類型被推斷,並且不能在defprotocol中直接覆蓋(還!)。對於非多態協議,「自我」是策略,否則就是(策略a b c),假設協議由a,b和c參數化。 – Ambrose 2014-12-08 01:41:02