【问题标题】:Clojure Speccing a natural numberClojure 指定一个自然数
【发布时间】:2017-04-11 14:27:32
【问题描述】:

natural number 是一个非负整数。您将如何使用 Clojure Spec 表达这一点?

【问题讨论】:

    标签: clojure clojure.spec


    【解决方案1】:

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

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

    但是请注意,这 不 匹配任意精度的整数,例如 bigint:

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

    【讨论】:

      【解决方案2】:

      还有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
      

      【讨论】:

      • 这看起来有问题:肯定是非负的 Doubles(Clojure 默认值)和 BigInts 也是自然数?
      • Double 是浮点精度,所以大多数都没有。但非负 BigInts 绝对是本规范不适用于的自然数。
      • 糟糕!意思是Long,而不是Double。
      • user=> (spec/conform ::natural-number (long 10)) 10. user=> (spec/conform ::natural-number (bigint 10)) :clojure.spec/invalid .
      【解决方案3】:

      您可以将其表示为 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 1970-01-01
        • 2015-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-27
        相关资源
        最近更新 更多