2014-12-11 17 views
1

我想將core.type註解應用到我的代碼中,但是我正在如何/何時實例化一個多態的核心函數,並從函數體內調用,進入一個絆腳石。如何在Clojure的core.typed中註釋多態核心函數?

排除故障,我已經瞭解到,我必須處理過濾器和計數特殊,因爲它們分別是多態和靜態的,匿名函數應該被拉出並註釋在綁定中。如果有人能夠根據下面的錯誤消息的輸出解釋如何對其進行註釋,我將非常感激。

這裏是我的別名:

(defalias Key-set (Set (Option Kw))) 
(defalias Player (Ref1 Key-set)) 
(defalias Set-vec (Vec (Set Kw))) 
(defalias Move (U ':x ':o)) 

目前的形式,該函數是在:

(ann first-two [Player -> (Option Seq)]) 
    (defn first-two [player] 
     (let [;; best guesses here 
      filter> (inst filter [[(U (Seqable Any) clojure.lang.Counted nil) -> Bool] -> Any] (Option (clojure.lang.Seqable [(U (Seqable Any) clojure.lang.Counted nil) -> Bool]))) 
      count>  (ann-form count [(U nil (Seqable Any) clojure.lang.Counted) -> Number]) 

      two-count? :- [(U nil (Seqable Any) clojure.lang.Counted)-> Bool], #(= (count> %) 2) 
      couples :- (Option (Seqable Key-set)), (concat adjacents opposite-corners opposite-sides)] 
     (first (filter> two-count? 
         (for [pair :- Key-set, couples] 
          (clojure.set/intersection pair @player)))))) 

類型檢查錯誤消息:

Type Error (tic_tac_toe/check.clj:52:5) Function filter> could not be applied to arguments: 


Domains: 
    [[[(U (Seqable Any) Counted nil) -> Bool] -> Any] -> Any :filters {:then (is (Option (clojure.lang.Seqable [(U nil (Seqable Any) clojure.lang.Counted) -> Bool])) 0), :else tt}] (Option (clojure.lang.Seqable [[(U (Seqable Any) Counted nil) -> Bool] -> Any])) 
    [[[(U (Seqable Any) Counted nil) -> Bool] -> Any] -> Any :filters {:then (! (Option (clojure.lang.Seqable [(U nil (Seqable Any) clojure.lang.Counted) -> Bool])) 0), :else tt}] (Option (clojure.lang.Seqable [[(U (Seqable Any) Counted nil) -> Bool] -> Any])) 
    [[[(U (Seqable Any) Counted nil) -> Bool] -> Any] -> Any] (Option (clojure.lang.Seqable [[(U (Seqable Any) Counted nil) -> Bool] -> Any])) 

Arguments: 
    [(U nil (Seqable Any) clojure.lang.Counted) -> Bool] (clojure.lang.LazySeq Any) 

Ranges: 
    (ASeq (Option (clojure.lang.Seqable [(U nil (Seqable Any) clojure.lang.Counted) -> Bool]))) 
    (ASeq (I [[(U (Seqable Any) Counted nil) -> Bool] -> Any] (Not (Option (clojure.lang.Seqable [(U nil (Seqable Any) clojure.lang.Counted) -> Bool]))))) 
    (ASeq [[(U (Seqable Any) Counted nil) -> Bool] -> Any]) 

ExceptionInfo Type Checker: Found 1 error clojure.core/ex-info (core.clj:4566) 

原始功能:

(defn first-two [player] 
    (let [couples (concat adjacents opposite-corners opposite-sides)] 
    (first (filter #(= (count %) 2) 
        (for [pair couples] 
        (clojure.set/intersection pair @player)))))) 

回答

1

你可以在別處提供類型以避免實例化filter

例如,此類型檢查。

(ns typed-test.core 
    (:refer-clojure :exclude [fn for]) 
    (:require [clojure.core.typed :as t 
      :refer [fn for Vec Coll Any Num]])) 

(filter (fn [a :- (Coll Any)] (= (count a) 2)) 
     (for [pair :- (Vec Num), {1 2 3 4}] 
      :- (Vec Num) 
      pair)) 

或許錯過了致for的呼叫的返回類型正在丟失太多信息。

inst只是用一些類型替換All活頁夾中的類型變量。

typed-test.core=> (cf identity) 
(t/All [x] [x -> x :filters {:then (! (t/U nil false) 0), :else (is (t/U nil false) 0)} :object {:id 0}]) 
typed-test.core=> (cf (t/inst identity Num)) 
[Num -> Num :filters {:then (! (t/U nil false) 0), :else (is (t/U nil false) 0)} :object {:id 0}] 
+0

這是for循環的返回類型。再次感謝,男士。 – kurofune 2014-12-12 04:34:09

0

只是一個快速的想法,因爲我現在沒有時間檢查你。

但是,類型clojure中的多態類型參數通常不直接映射到參數。快速瀏覽一下,我認爲這是問題的根源。

例如,假設我們定義了一個多態樂趣並且我們想實例化它。

(ann f (All [x] [[x -> Bool] x -> Integer])) 
(defn f [predicate? value] (if (f value) 1 0)) 

要正確初始化它,你將不得不去這樣

((inst f String) (typed/fn [x :- String] :- Bool true) "lol") 

,而不是

((inst f [String -> Bool]) (typed/fn [x :- String] :- Bool true) "lol2") ;; baaaad baaaad 

現在我必須回去工作T_T花了太多的時間定製我的emacs今天ahah ...

+0

我搞砸了吧。你的解釋對我來說有很多關於多態類型的解釋,但我仍然不確定我需要做些什麼來修復這個例子,我似乎沒有做任何事情。 – kurofune 2014-12-11 19:14:54

相關問題