【问题标题】:Why some? returns true when it takes false as a parameter in Clojure?为什么有些?在 Clojure 中将 false 作为参数时返回 true?
【发布时间】:2016-09-29 10:36:32
【问题描述】:

我无法理解 Clojure 中 some? 函数的意图。

我需要一些函数(内置)在需要时返回 false(nil 或 false)。

示例如下:

(some? "1")
=> true

(some? nil)
=> false

(some? false) ;;Which is odd!!
=> true

【问题讨论】:

  • 有趣的是nil?some?做的完全一样。
  • @S4M 不,它没有。 (nil? nil) 返回 true(some? nil) 返回 'false`。
  • @PiotrekBzdyl 你是对的,(not (nil? false)) 返回true(not (nil? nil)) 返回false

标签: function clojure functional-programming lisp clojurescript


【解决方案1】:

不知道为什么some? 会这样。但你要找的是boolean


  1. https://clojuredocs.org/clojure.core/boolean

【讨论】:

    【解决方案2】:

    查看some?的文档:

    (some? x)
    
    Returns true if x is not nil, false otherwise.
    

    false 绝对不是nil 因此(some? false) 返回true

    它是nil?的补充

    (= (some? x) (not (nil? x))
    

    正如@delta 建议的那样,您可以使用boolean 来检查某些内容是否不是nilfalse

    【讨论】:

    • 我要补充一点,语义上 some? 完全对应于它的标题,这意味着它检查,该值是 something,而只有 nil 被认为是 没有在clojure中。显然false 是什么。所以这种行为没有什么奇怪的。
    • @leetwinski 同意,但是,人们经常感到困惑,因为在some 谓词返回的逻辑真值(即非假)被视为匹配。不过,那里的命名也是一致的,说“给我一些与谓词匹配的元素”。 some-> 的命名也是一致的,它再次将 false 视为 some?
    • 确实.. 我宁愿把它命名为something? 真的.. 但是好吧.. Rich 知道得更好)
    【解决方案3】:

    有效的source for some?

    (defn some? [x] (not (nil? x)))
    

    最好将其称为not-nil?Tupelo 作为别名提供。

    正如其他人所说,您正在寻找的功能是boolean

    【讨论】:

      【解决方案4】:

      更简单,使用IF

      user=> (if "1" true false)
      true
      user=> (if nil true false)
      false
      user=> (if false true false)
      false
      

      【讨论】:

        【解决方案5】:

        虽然有不止一种方法可以满足您的要求,但我认为最简单的方法是使用 truthy?falsey? 函数 from the Tupelo library

        事实并非模棱两可

        Clojure 结合了 Java 和 Lisp 的世界。不幸的是,这两个 世界对真理有不同的看法,所以 Clojure 接受两者都是错误的 和 nil 为假。但是,有时您想强制合乎逻辑 值转换为文字真或假值,因此我们提供了一种简单的方法 这样做:

        (truthy? arg)
          Returns true if arg is logical true (neither nil nor false);
          otherwise returns false.
        
        (falsey? arg)
          Returns true if arg is logical false (either nil or false);
          otherwise returns false. Equivalent to (not (truthy? arg)).
        

        说实话?和虚假?是函数(而不是特殊形式或宏),我们可以将它们用作过滤器的参数或任何其他需要高阶函数的地方:

        (def data [true :a 'my-symbol 1 "hello" \x false nil] )
        
        (filter truthy? data)
        ;=> [true :a my-symbol 1 "hello" \x]
        (filter falsey? data)
        ;=> [false nil]
        
        (is (every? truthy? [true :a 'my-symbol 1 "hello" \x] ))
        (is (every? falsey? [false nil] ))
        
        (let [count-if (comp count keep-if) ]
          (let [num-true    (count-if truthy? data)   ; <= better than (count-if boolean data)
                num-false   (count-if falsey? data) ] ; <= better than (count-if not     data)
            (is (and  (= 6 num-true)
                      (= 2 num-false) )))))
        

        【讨论】:

        • 我认为需要的函数是truthy?,而不是falsey?
        • 考虑到语言本身在所有条件形式中都尊重逻辑真理,我认为这些谓词最多可在 99.99% 的情况下增加可读性。 falsey? 正是 not。 IDK 是 keep-if 的含义,但考虑惯用的 (filter identity data)(filter not data) - 我不会对此表示反对,因为这是通过 SICP 风格的上下文重新定义增加可读性的一个很好的例子,但如果你提供一个会更好出于学习目的,此处的行实现而不是链接到它。
        • 您是正确的,主要目的是可读性,以便代码文本更准确地说明它打算做什么。这对学习 Clojure 的人特别有帮助。使用not 并不难读,但没有与truthy? 类似的逆向。当然,不能使用if,因为它是一种特殊形式。因此,瘦包装器 fn 的 truthy?falsey? 强制转换为 true/false。虽然boolean 有效,但在我注意到它之前,我已经使用了 2 年的 Clojure!即便如此,在您测试并验证其所有行为之前,文档仍使其看起来像是“演员”。
        猜你喜欢
        • 2015-10-03
        • 2013-09-18
        • 2011-05-22
        • 2017-07-29
        • 2021-11-10
        • 2010-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多