我想将core.type注释应用于我的代码,但是遇到了如何/何时实例化多态的核心函数,从函数体内调用的绊脚石。
对此进行故障排除,我了解到我必须对filter和count进行特殊处理,因为它们分别是多态和静态的,应该在let绑定中提取和注释匿名函数。如果有人可以根据下面的错误消息的输出解释如何注释这个,我真的很感激。
以下是我的别名:
(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 checker错误消息:
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))))))
答案 0 :(得分: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}]
答案 1 :(得分: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
现在我必须回去工作,花了太多时间来定制我的emacs今天......