Clojure规范自然数

3

自然数是一个非负整数。如何使用Clojure Spec表达这个概念?

3个回答

6

这已经是1.9中的谓词函数,匹配固定精度的非负整数:

(s/valid? nat-int? 1)
; true

请注意,这并不适用于类似大整数(bigints)等任意精度整数:

(s/valid? nat-int? (bigint 1))
; false

1
你可以将其表示为一个由"integer?"谓词和它是否大于0组成的复合语句。
(spec/def ::natural-number
  (spec/and integer? (partial <= 0)))

(spec/exercise ::natural-number)
=> ([0 0] [0 0] [0 0] [1 1] [5 5] [5 5] [0 0] [0 0] [0 0] [19 19])

这适用于固定和任意精度整数:

(spec/valid? ::natural-number (long 0))
    => true
(spec/valid? ::natural-number (int 0))
    => true
(spec/valid? ::natural-number (bigint 0))
=> true

1

还有一个spec/int-in函数,允许您指定一个范围,例如

(spec/def ::natural-number
  (spec/int-in 0 Integer/MAX_VALUE))

(spec/exercise ::natural-number)
=> ([1 1] [1 1] [0 0] [0 0] [1 1] [3 3] [4 4] [4 4] [50 50] [1 1])

请注意,spec/int-in 不匹配类似 bigint 的任意精度整数:
(spec/valid? (spec/int-in 0 Integer/MAX_VALUE) (bigint 1))
=> false

这看起来有点可疑:肯定非负的Double(Clojure默认)和BigInt也是自然数吧? - Thumbnail
Double是浮点精度,所以大多数情况下不是自然数。但非负BigInts绝对是自然数,而这个规范不适用于它们。 - Rovanion
糟糕!应该用“Long”,而不是“Double”。 - Thumbnail
用户=> (spec/conform ::natural-number (long 10)) 10. 用户=> (spec/conform ::natural-number (bigint 10)) :clojure.spec/invalid. - Rovanion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接