2014-12-08 2 views
1

나는 틱택에 발가락 게임을하고 내 전략에 대한 프로토콜을 만들었습니다. 게임이 잘 돌아가고 있으므로이 기회를 통해 핵심 기술을 연마 할 수 있습니다. (아래 그림 참조) 나는 프로토콜을 주석, 그러나 나는 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/protocol입니다. 프로토콜을 사용했을 때 콘솔이 나를 짖어 대었습니다. 구문이 더 이상 사용되지 않는다고 말했습니다. github 페이지와 clojure-doc.org의 문서를 살펴 보았습니다. 방법을 유형에 매핑하는 데 사용할 수있는 선택적 :methods 키워드가 있음을 알게되었습니다. 이것은 내 코드에서 많은 반복을 제거 할 수 있다고 생각하지만 사용법의 예를 찾을 수 없었다. 프로토콜의 주요 전략 방법은 모두 부작용이 있으며 nil을 반환합니다. 유효성 검사 방법은 유효성을 검사하는 nil 또는 원래 Strategy 메서드를 반환합니다. 내가 거기에 구문을 가지고 있는지 모르겠지만, 코드는 LightTable에서 Fn 서명의 유무에 상관없이 잘 평가되고 있으며 core.typed 위키는 항상 필요하지는 않다는 것을 의미합니다.

나는이 놀라운 도서관을 배우면서 이곳의 첨단에있는 것처럼 느껴지고 나의 이해를 도울 수있는 통찰력있는 조언을 주시면 감사하겠습니다.

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-protocol은 필요하지 않습니다. clojure.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

+0

이러한 메소드의 입력 유형이 유추됩니까? – kurofune

+0

'자체'유형이 추론되며 defprotocol에서 직접 재정의 될 수는 없습니다 (아직!). 비 다형성 프로토콜의 경우 'self'는 전략이며 그렇지 않은 경우 프로토콜은 a, b 및 c로 매개 변수화되었다고 가정합니다 (전략 a b c). – Ambrose

관련 문제