问题描述
我将再次通过项目euler来开发和磨练我的core.typed技能。然而,我有一个很难理解类型检查器的输出。我在阅读了几篇关于core.typed的介绍材料以及一些关于core.typed wiki的信息后要求。
我使用下面的代码,请注意对的注释应用
以及将 num
映射到函数中的输入 euler3
没有效果。仍然生成错误消息。请忽略显而易见的因素
和 prime?
函数。我选择了天真的实现,让我专注于类型注释。
(ns euler-clj.euler3
/ pre>
项目euler问题3.
使用一个非常天真的素数测试器,将使用筛选或概率
prime算法用于较大的问题集。
数字600851475143的最大素因子是多少?
(:require [clojure.core.typed:refer
[ann check-ns Int fn> non-nil-return Seq cf]]
[euler-clj.euler1 :as e1]))
(非nil-return clojure.lang.Numbers / quotient:all)
(ann ^:no-check clojure.core / apply [[Number Number * - > Number](Seq Number) - > Number])
(ann factor [Int->(Seq Int)])
(defn factors
[ n]
(filter(fn> [m:-Int](e1 / div-by mn))(range 1(inc(n 2)))))
非常差的主函数,应该是筛/概率。
;还将1标识为不正确。
(ann prime?[Int - &Boolean])
(defn prime?[n](= [1](factors n)))
(ann euler3 [ int - > Number])
(defn euler3
[n]
(apply max(map num(filter prime?(factors n))))
$ b b(ann-main [ - > nil])
(defn -main
[]
(prn(euler3 600851475143)))
这会产生以下错误:
类型错误(euler- clj.euler3:26:3)应用的错误参数:
目标:(Fn [java.lang.Number java.lang.Number * - > java.lang.Number])
参数:(clojure.core.typed / Seq java.lang.Number)
in:(clojure.core / apply clojure.core / max(clojure.core / map clojure.core / num .core / filter euler-clj.euler3 / prime?
(euler-clj.euler3 / factors n))))
ExceptionInfo类型检查器:发现1错误clojure。 core / ex-info(core.clj:4327)
开始收集euler-clj.euler3
开始收集euler-clj.euler1
收集euler-clj.euler1
收集euler-clj.euler3
在62.584894 msecs中收集2个命名空间
开始检查euler-clj.euler1
在165.76663 msecs中检查的euler-clj.euler1
开始检查euler-clj。 euler3
选中的euler-clj.euler3 in 200.997234 msecs
选中了2个命名空间(约。 60 lines)in 430.302357 msecs
我需要提供什么类型的注释来申请接受最大值,然后接受这个数字? / p>
感谢
解决方案首先,您不应该提供自己的类型
apply
;
在这种情况下,core.typed需要一点说服
max $ c
这里有一种方法:
<$> c $ c>(ann euler3 [Int - > Number])
(defn euler3
[n]
(let [[f& r]因素n)))]
(如果f
(apply max fr)
(throw(Exception。No prime factors))))
I'm going through project euler again to develop and hone my core.typed skills. However I am having a ton of difficulty understanding the output of the type checker. I'm asking after reading several introductory materials to core.typed as well as some information on the core.typed wiki.
I am using the following code, and please note that the annotation to
apply
, as well as mappingnum
over the input in functioneuler3
has no effect. The error message is still generated. Please ignore the obviously badfactors
andprime?
functions. I chose naive implementations to allow me to focus on the type annotations.(ns euler-clj.euler3 "Project euler problem 3. Uses a very naive prime tester, would use a sieve or probabilistic prime algorithm for a larger problem set. What is the largest prime factor of the number 600851475143?" (:require [clojure.core.typed :refer [ann check-ns Int fn> non-nil-return Seq cf]] [euler-clj.euler1 :as e1])) (non-nil-return clojure.lang.Numbers/quotient :all) (ann ^:no-check clojure.core/apply [[Number Number * -> Number] (Seq Number) -> Number]) (ann factors [Int -> (Seq Int)]) (defn factors [n] (filter (fn> [m :- Int] (e1/div-by m n)) (range 1 (inc (quot n 2))))) ; Very bad prime function, should be sieve/probabilistic. ; Also identifies 1 as prime incorrectly. (ann prime? [Int -> Boolean]) (defn prime? [n] (= [1] (factors n))) (ann euler3 [Int -> Number]) (defn euler3 [n] (apply max (map num (filter prime? (factors n))))) (ann -main [-> nil]) (defn -main [] (prn (euler3 600851475143)))
This produces the following error:
Type Error (euler-clj.euler3:26:3) Bad arguments to apply: Target: (Fn [java.lang.Number java.lang.Number * -> java.lang.Number]) Arguments: (clojure.core.typed/Seq java.lang.Number) in: (clojure.core/apply clojure.core/max (clojure.core/map clojure.core/num (clojure.core/filter euler-clj.euler3/prime? (euler-clj.euler3/factors n)))) ExceptionInfo Type Checker: Found 1 error clojure.core/ex-info (core.clj:4327) Start collecting euler-clj.euler3 Start collecting euler-clj.euler1 Finished collecting euler-clj.euler1 Finished collecting euler-clj.euler3 Collected 2 namespaces in 62.584894 msecs Start checking euler-clj.euler1 Checked euler-clj.euler1 in 165.76663 msecs Start checking euler-clj.euler3 Checked euler-clj.euler3 in 200.997234 msecs Checked 2 namespaces (approx. 60 lines) in 430.302357 msecsWhat type annotations do I need to provide to get apply to accept max and then this seq of numbers?
Thanks
解决方案Firstly, you should not provide your own type for
apply
; it's implemented as a special case in the type checker.In this case, core.typed needs a bit of convincing that
max
will never be called with zero arguments.Here's one approach:
(ann euler3 [Int -> Number]) (defn euler3 [n] (let [[f & r] (map num (filter prime? (factors n)))] (if f (apply max f r) (throw (Exception. "No prime factors")))))
这篇关于Clojure Core.Typed注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!