Cuando escribe una expresión de coincidencia de patrón, no puede usar funciones arbitrarias en sus patrones. Solo puede usar constructores, que se parecen a funciones no evaluadas. Por ejemplo, la función "+" se define en enteros. Entonces la expresión 1+2
se evalúa y da 3; la función "+" se evalúa, por lo que no puede coincidir en x+y
. Aquí hay un intento de definir una función en los números naturales que verifica si el número es cero:
let f x = match x with
| 0 -> false
| a+1 -> true
;;
¡Esto no puede funcionar! Por la misma razón, su ejemplo con cadenas no puede funcionar. La función "^" se evalúa en cadenas, no es un constructor.
La coincidencia en x+1
funcionaría solo si los números fueran expresiones no evaluadas simbolizadas hechas del operador no evaluado +
y una constante simbólica 1
. Este no es el caso en OCAML. Los enteros se implementan directamente a través de números de máquina.
Cuando coincide con un tipo de variante, hace coincidir en constructores, que son expresiones no evaluadas. Por ejemplo:
# let f x = match x with
| Some x -> x+1
| None -> 0
;;
val f : int option -> int = <fun>
Esto funciona porque el tipo 'a option
está hecho de una expresión simbólica, como Some x
. Aquí, Some
no es una función que se evalúa y proporciona algún otro valor, sino más bien un "constructor", que se puede considerar como una función que nunca se evalúa. La expresión Some 3
ya no se evalúa; permanece como está. Es solo en tales funciones que puede emparejar patrones.
Las listas también son expresiones simbólicas, no evaluadas, construidas a partir de constructores; el constructor es ::
. El resultado de x :: y :: []
es una expresión no evaluada, que se representa mediante la lista [x;y]
solo por conveniencia cosmética. Por esta razón, puede emparejar patrones en listas.
Además de la explicación a continuación: ¿Dónde en la cadena debe el compilador incluso dividir la cadena? "abc" a "a" "bc" o "ab" "c" – 0x434D53