调用 clojure.core/fn 不符合规范
Call to clojure.core/fn did not conform to spec
我收到这条消息:
Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/fn did not conform to spec:
In: [0] val: (- (int p1__148#) 48) fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?
In: [0 0] val: - fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-n :args] predicate: vector?
#:clojure.spec.alpha{:problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val (- (int p1__148#) 48), :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0]} {:path [:args :bs :arity-n :args], :pred clojure.core/vector?, :val -, :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0 0]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x58faa93b "clojure.spec.alpha$regex_spec_impl$reify__2436@58faa93b"], :value ((- (int p1__148#) 48) [x] (* x x)), :args ((- (int p1__148#) 48) [x] (* x x))}, compiling:(/Users/hassan/Desktop/fourclojure/src/fourclojure/120.clj:8:31)
at clojure.lang.Compiler.checkSpecs(Compiler.java:6891)
at clojure.lang.Compiler.macroexpand1(Compiler.java:6907)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6989)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyze(Compiler.java:6729)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyze(Compiler.java:6729)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyze(Compiler.java:6729)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyze(Compiler.java:6729)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.access0(Compiler.java:38)
at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:595)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
at clojure.lang.Compiler.analyze(Compiler.java:6773)
at clojure.lang.Compiler.analyze(Compiler.java:6729)
at clojure.lang.Compiler.eval(Compiler.java:7066)
at clojure.lang.Compiler.load(Compiler.java:7514)
at clojure.lang.Compiler.loadFile(Compiler.java:7452)
at clojure.main$load_script.invokeStatic(main.clj:278)
at clojure.main$script_opt.invokeStatic(main.clj:338)
at clojure.main$script_opt.invoke(main.clj:333)
at clojure.main$main.invokeStatic(main.clj:424)
at clojure.main$main.doInvoke(main.clj:387)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.main.main(main.java:37)
Caused by: clojure.lang.ExceptionInfo: Call to clojure.core/fn did not conform to spec:
In: [0] val: (- (int p1__148#) 48) fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?
In: [0 0] val: - fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-n :args] predicate: vector?
{:clojure.spec.alpha/problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val (- (int p1__148#) 48), :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0]} {:path [:args :bs :arity-n :args], :pred clojure.core/vector?, :val -, :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0 0]}), :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x58faa93b "clojure.spec.alpha$regex_spec_impl$reify__2436@58faa93b"], :clojure.spec.alpha/value ((- (int p1__148#) 48) [x] (* x x)), :clojure.spec.alpha/args ((- (int p1__148#) 48) [x] (* x x))}
at clojure.core$ex_info.invokeStatic(core.clj:4739)
at clojure.core$ex_info.invoke(core.clj:4739)
at clojure.spec.alpha$macroexpand_check.invokeStatic(alpha.clj:689)
at clojure.spec.alpha$macroexpand_check.invoke(alpha.clj:681)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.lang.Compiler.checkSpecs(Compiler.java:6889)
... 45 more
当我运行这段代码时:
(defn count-less-than-square [l]
(->>
l
(map (fn [n] (->> n
str
(map #(-> % int (- 48) (fn [x] (* x x)))) ; The problem is that fn
(reduce +)
(list n))))
(filter #(< (first %) (second %)))
count))
然而,当我运行它是这样的:
(defn pow [a b] (reduce * 1 (repeat b a)))
(defn count-less-than-square [l]
(->>
l
(map (fn [n] (->> n
str
(map #(-> % int (- 48) (pow 2)))
(reduce +)
(list n))))
(filter #(< (first %) (second %)))
count))
(pp/pprint (count-less-than-square (range 30)))
它工作正常。
为什么 (fn [x] (* x x))
崩溃了?它在 REPL 中运行良好。
问题是您正在使用的 ->
宏将线程值插入第一个位置,就在 fn
符号之后。
所以这个:
(map #(-> % int
(- 48)
(fn [x] (* x x))))
变成类似:
(map #(fn
(- (int %) 48)
[x]
(* x x)))
这显然是无效的,因为 fn
期望第一个 arg 是函数参数的向量,这就是错误消息试图说明的内容:
fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?
我收到这条消息:
Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/fn did not conform to spec: In: [0] val: (- (int p1__148#) 48) fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector? In: [0 0] val: - fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-n :args] predicate: vector? #:clojure.spec.alpha{:problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val (- (int p1__148#) 48), :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0]} {:path [:args :bs :arity-n :args], :pred clojure.core/vector?, :val -, :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0 0]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x58faa93b "clojure.spec.alpha$regex_spec_impl$reify__2436@58faa93b"], :value ((- (int p1__148#) 48) [x] (* x x)), :args ((- (int p1__148#) 48) [x] (* x x))}, compiling:(/Users/hassan/Desktop/fourclojure/src/fourclojure/120.clj:8:31) at clojure.lang.Compiler.checkSpecs(Compiler.java:6891) at clojure.lang.Compiler.macroexpand1(Compiler.java:6907) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6989) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyze(Compiler.java:6729) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022) at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyze(Compiler.java:6729) at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881) at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyze(Compiler.java:6729) at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881) at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyze(Compiler.java:6729) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022) at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.access0(Compiler.java:38) at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:595) at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003) at clojure.lang.Compiler.analyze(Compiler.java:6773) at clojure.lang.Compiler.analyze(Compiler.java:6729) at clojure.lang.Compiler.eval(Compiler.java:7066) at clojure.lang.Compiler.load(Compiler.java:7514) at clojure.lang.Compiler.loadFile(Compiler.java:7452) at clojure.main$load_script.invokeStatic(main.clj:278) at clojure.main$script_opt.invokeStatic(main.clj:338) at clojure.main$script_opt.invoke(main.clj:333) at clojure.main$main.invokeStatic(main.clj:424) at clojure.main$main.doInvoke(main.clj:387) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.lang.Var.applyTo(Var.java:702) at clojure.main.main(main.java:37) Caused by: clojure.lang.ExceptionInfo: Call to clojure.core/fn did not conform to spec: In: [0] val: (- (int p1__148#) 48) fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector? In: [0 0] val: - fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-n :args] predicate: vector? {:clojure.spec.alpha/problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val (- (int p1__148#) 48), :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0]} {:path [:args :bs :arity-n :args], :pred clojure.core/vector?, :val -, :via [:clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [0 0]}), :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x58faa93b "clojure.spec.alpha$regex_spec_impl$reify__2436@58faa93b"], :clojure.spec.alpha/value ((- (int p1__148#) 48) [x] (* x x)), :clojure.spec.alpha/args ((- (int p1__148#) 48) [x] (* x x))} at clojure.core$ex_info.invokeStatic(core.clj:4739) at clojure.core$ex_info.invoke(core.clj:4739) at clojure.spec.alpha$macroexpand_check.invokeStatic(alpha.clj:689) at clojure.spec.alpha$macroexpand_check.invoke(alpha.clj:681) at clojure.lang.AFn.applyToHelper(AFn.java:156) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.lang.Var.applyTo(Var.java:702) at clojure.lang.Compiler.checkSpecs(Compiler.java:6889) ... 45 more
当我运行这段代码时:
(defn count-less-than-square [l]
(->>
l
(map (fn [n] (->> n
str
(map #(-> % int (- 48) (fn [x] (* x x)))) ; The problem is that fn
(reduce +)
(list n))))
(filter #(< (first %) (second %)))
count))
然而,当我运行它是这样的:
(defn pow [a b] (reduce * 1 (repeat b a)))
(defn count-less-than-square [l]
(->>
l
(map (fn [n] (->> n
str
(map #(-> % int (- 48) (pow 2)))
(reduce +)
(list n))))
(filter #(< (first %) (second %)))
count))
(pp/pprint (count-less-than-square (range 30)))
它工作正常。
为什么 (fn [x] (* x x))
崩溃了?它在 REPL 中运行良好。
问题是您正在使用的 ->
宏将线程值插入第一个位置,就在 fn
符号之后。
所以这个:
(map #(-> % int
(- 48)
(fn [x] (* x x))))
变成类似:
(map #(fn
(- (int %) 48)
[x]
(* x x)))
这显然是无效的,因为 fn
期望第一个 arg 是函数参数的向量,这就是错误消息试图说明的内容:
fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?