Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
序列集合的Clojure等式 P>我注意到Culjule(1.4)似乎很乐意考虑向量相同于相同向量的 SEQ < /代码>,但同样不适用于图: (= [1 2] (seq [1 2])) => true (= {1 2} (seq {1 2})) => false_Clojure_Sequence_Equality - Fatal编程技术网

序列集合的Clojure等式 P>我注意到Culjule(1.4)似乎很乐意考虑向量相同于相同向量的 SEQ < /代码>,但同样不适用于图: (= [1 2] (seq [1 2])) => true (= {1 2} (seq {1 2})) => false

序列集合的Clojure等式 P>我注意到Culjule(1.4)似乎很乐意考虑向量相同于相同向量的 SEQ < /代码>,但同样不适用于图: (= [1 2] (seq [1 2])) => true (= {1 2} (seq {1 2})) => false,clojure,sequence,equality,Clojure,Sequence,Equality,为什么=的行为应该以这种方式有所不同?我想这是因为序列顺序以及特定位置的值都很重要,而在map中键/值的顺序并不重要,语义之间的这种差异导致了这一点,如示例代码所示 有关更多详细信息,请查看文件中的mapEquals 它检查另一个对象是否映射,然后返回false。在我看来,这个示例指出了clojure中值相等的概念中的一点不一致,在这种情况下,它们是从同一类型派生的不同类型(通过seq函数)。可以很好地说,这并不矛盾,因为它将派生类型与派生类型进行比较,我可以理解,如果使用向量将相同的逻辑应用于

为什么
=
的行为应该以这种方式有所不同?

我想这是因为序列顺序以及特定位置的值都很重要,而在map中键/值的顺序并不重要,语义之间的这种差异导致了这一点,如示例代码所示

有关更多详细信息,请查看文件中的
mapEquals


它检查另一个对象是否映射,然后返回false。

在我看来,这个示例指出了clojure中值相等的概念中的一点不一致,在这种情况下,它们是从同一类型派生的不同类型(通过
seq
函数)。可以很好地说,这并不矛盾,因为它将派生类型与派生类型进行比较,我可以理解,如果使用向量将相同的逻辑应用于相同的示例(请注意底部)

user=> (seq {1 2})
([1 2])
user=> (type {1 2})
clojure.lang.PersistentArrayMap
内容类型相同:

user> (type (first (seq {1 2})))
clojure.lang.MapEntry
user> (type (first {1 2}))
clojure.lang.MapEntry

user> (= (type (first {1 2})) (type (first (seq {1 2}))))
true
user> (= (first {1 2}) (first (seq {1 2})))
true
序列具有相同的值

user> (map = (seq {1 2}) {1 2})
(true)
但它们并不平等 用户>(={12}(seq{12})) 假的

对于较长的地图也是如此:

user> (map = (seq {1 2 3 4}) {1 2 3 4})
(true true)
user> (map = (seq {1 2 3 4 5 6}) {1 2 3 4 5 6})
(true true true)
user> (map = (seq {9 10 1 2 3 4 5 6}) {9 10 1 2 3 4 5 6})
(true true true true)    
即使它们的顺序不同:

但是,如果包含的类型不同,则情况也不同:-(

编辑:这并不总是正确的,请参见以下内容: 为了解决这个问题,您可以在比较之前将所有内容转换为seq,这(我认为)是安全的,因为seq函数总是以相同的方式迭代整个数据结构,并且结构是不可变的值,
seq的
seq
seq

user> (= (seq {9 10 1 2 3 4 5 6}) {1 2 3 4 5 6 9 10})
false
user> (= (seq {9 10 1 2 3 4 5 6}) (seq {1 2 3 4 5 6 9 10}))
true

矢量的处理方式不同:

user> (= [1 2 3 4] (seq [1 2 3 4]))
true
也许理解这些细微的不一致是学习一门语言的一部分,或者有一天这可以改变(尽管我不会屏住呼吸)


编辑:

我发现两个映射为同一个值生成不同的序列,因此仅在映射上调用seq不会给您提供正确的映射等式:

user> (seq (zipmap  [3 1 5 9][4 2 6 10]))
([9 10] [5 6] [1 2] [3 4])
user> (seq {9 10 5 6 1 2 3 4})
([1 2] [3 4] [5 6] [9 10])
user> 
user> (def a (zipmap  [3 1 5 9][4 2 6 10]))
#'user/a
user> (def b {9 10 5 6 1 2 3 4})
#'user/b
user> (every? true? (map #(= (a %) (b %)) (keys a)))
true
下面是一个我称之为适当映射平等的示例:

user> (seq (zipmap  [3 1 5 9][4 2 6 10]))
([9 10] [5 6] [1 2] [3 4])
user> (seq {9 10 5 6 1 2 3 4})
([1 2] [3 4] [5 6] [9 10])
user> 
user> (def a (zipmap  [3 1 5 9][4 2 6 10]))
#'user/a
user> (def b {9 10 5 6 1 2 3 4})
#'user/b
user> (every? true? (map #(= (a %) (b %)) (keys a)))
true

Clojure的
=
可以看作是通过两个步骤进行比较:

  • 检查被比较对象的类型是否属于同一个“相等分区”,即其成员可能相等的一类类型(取决于给定数据结构的确切成员,而不是分区中的特定类型)

  • 如果是这样,检查被比较的事物是否是相等的

  • 一个这样的等分是“连续”事物的等分。向量被认为是连续的:

    (instance? clojure.lang.Sequential [])
    ;= true
    
    各种类型的序列号如下:

    (instance? clojure.lang.Sequential (seq {1 2}))
    ;= true
    
    因此,当(且仅当)向量的对应元素相等时,认为向量等于序列

    (请注意,
    (seq{})
    产生
    nil
    ,它不是顺序的,并将“不等于”与
    []
    等进行比较。)

    另一方面,映射本身构成了一个相等分区,因此,虽然哈希映射可能被视为等同于已排序的映射,但它永远不会被视为等同于seq。特别是,它不等同于其条目的seq,而seq正是
    (seq some map)
    产生的结果。

    (seq some hash map)
    提供一系列条目(键/值对)

    例如:

    foo.core=> (seq {:a 1 :b 2 :c 3})
    ([:a 1] [:c 3] [:b 2])
    
    这与
    [:a1:b2:c3]
    不同