2009-09-11 27 views
51

Parece ser una comparación de equivalencia para algunos tipos, pero no para cadenas.¿Tiene! = Significado en OCaml?

# 3 != 3;; 
- : bool = false 
# 3 != 2;; 
- : bool = true 

Esto es como se esperaba.

# "odp" = "odp";; 
- : bool = true 
# "odp" != "odp";; 
- : bool = true 
# "odp" <> "odp";; 
- : bool = false 

¿Por qué "odp" != "odp" evaluar a true? ¿Qué está haciendo realmente? ¿No debería generar un error de tipo?

Respuesta

76

ha experimentado la diferencia entre la igualdad estructural y física.

<> es = (igualdad estructural) como != es == (igualdad física)

"odg" = "odg" (* true *) 
"odg" == "odg" (* false *) 

es falso, ya que cada se instancia en diferentes ubicaciones de la memoria, haciendo:

let v = "odg" 
v == v (* true *) 
v = v (* true *) 

La mayor parte de el momento en que querrá usar = y <>.

edición acerca de cuándo la igualdad estructural y física son equivalentes:

Usted puede utilizar el what_is_it function y descubrir todos los tipos que serían iguales tanto estructural como físicamente. Como se menciona en los comentarios a continuación, y en el artículo vinculado, los caracteres, enteros, unidades, listas vacías y algunas instancias de tipos variantes tendrán esta propiedad.

+1

+1 que fueron los más rápidos ... :) – LB40

14

Lo contrario para el operador != es == operador, no el = uno.

# "a" != "a" ;; 
- : bool = true 
# "a" == "a" ;; 
- : bool = false 

El operador == es una "igualdad física". Cuando escribe "a" == "a", compara dos instancias diferentes de cadenas que se parecen, así que el operador devuelve false. Si bien tener una instancia hace que sea return true:

# let str = "a" 
    in str == str ;; 
- : bool = true 
# let str = "a" 
    in str != str ;; 
- : bool = false 
0

enteros son el único tipo donde la igualdad física y estructural son los mismos, porque enteros son el único tipo que se sacó de la caja

+1

enteros y caracteres son los únicos tipos ... FTFY – nlucaroni

+1

booleanos también ... – LB40

+1

para acortar esta lista hacia arriba, realmente debería decir algo entero como, ya que también incluye listas vacías y la unidad – nlucaroni

12

Una explicación rápida sobre == y != en OCaml además de todas las respuestas correctas que ya se han proporcionado:

1/== y != exponen detalles de implementación que realmente no desea conocer. Ejemplo:

# let x = Some [] ;; 
val x : 'a list option = Some [] 
# let t = Array.create 1 x ;; 
val t : '_a list option array = [|Some []|] 
# x == t.(0) ;; 
- : bool = true 

Hasta ahora, todo bien: x y t.(0) son físicamente iguales porque t.(0) contiene un puntero al mismo bloque que está señalando a x. Esto es lo que dicta el conocimiento básico de la implementación. PERO:

# let x = 1.125 ;; 
val x : float = 1.125 
# let t = Array.create 1 x ;; 
val t : float array = [|1.125|] 
# x == t.(0) ;; 
- : bool = false 

Lo que está viendo aquí son los resultados de una optimización de otro modo útil que involucra flotadores.

2/Por otro lado, existe una forma segura de usar ==, y eso es una manera rápida pero incompleta de verificar la igualdad estructural.

Si está escribiendo una función de la igualdad en los árboles binarios

let equal t1 t2 = 
    match ... 

cheques t1 y t2 por la igualdad física es una forma rápida de detectar que son, obviamente, estructuralmente iguales, sin ni siquiera tener que recursivo y leerlos. Es decir:

let equal t1 t2 = 
    if t1 == t2 
    then true 
    else 
    match ... 

Y si se tiene en cuenta que en OCaml el operador “booleano o” es “perezosa”,

let equal t1 t1 = 
    (t1 == t2) || 
    match ... 
2

Son como dos s "Tom" en su clase! Porque:

En este caso, "odp" = "odp" porque son DOS cuerdas con MISMO VALOR !!

Así que no son == porque son DOS tienda de diferentes cadenas en diferentes (Memoria) ubicación

Ellos son = porque tienen el valor cadena idéntica.

Un paso más profundo, "odp" es una variable anónima. Y dos variables anónimas conducen a este Dos cadenas.

Para su comodidad:

# "odp" = "odp";; 
- : bool = true 
# "odp" != "odp";; 
- : bool = true 
# "odp" <> "odp";; 
- : bool = false