2014-12-08 52 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