Clojure Core.Typed注释 [英] Clojure Core.Typed annotation for apply

查看:120
本文介绍了Clojure Core.Typed注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将再次通过项目euler来开发和磨练我的core.typed技能。然而,我有一个很难理解类型检查器的输出。我在阅读了几篇关于core.typed的介绍材料以及一些关于core.typed wiki的信息后要求。



我使用下面的代码,请注意对的注释应用以及将 num 映射到函数中的输入 euler3 没有效果。仍然生成错误消息。请忽略显而易见的因素 prime?函数。我选择了天真的实现,让我专注于类型注释。

 (ns euler-clj.euler3 
项目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)))
/ pre>

这会产生以下错误:

 
类型错误(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>(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 mapping num over the input in function euler3 has no effect. The error message is still generated. Please ignore the obviously bad factors and prime? 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 msecs

What 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注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆