Pregunta

Este es un seguimiento de ¿Por qué recibo 'patrones no exhaustivos en la función ...' cuando invoco mi función de subcadena Haskell?

Yo entiendo que el uso de -Wall, GHC puede advertir en contra de los patrones no exhaustivos. Me pregunto ¿cuál es la razón detrás no por lo que es un error en tiempo de compilación por defecto dado que siempre es posible definir explícitamente una función parcial:

f :: [a] -> [b] -> Int
f [] _  = error "undefined for empty array"
f _ []  = error "undefined for empty array"
f (_:xs) (_:ys) = length xs + length ys

La cuestión no es GHC-específica.

¿Es porque ...

  • nadie quería hacer cumplir un compilador de Haskell para llevar a cabo este tipo de análisis?
  • un patrón de búsqueda no exhaustiva puede encontrar algunos pero no todos los casos?
  • funciones parcialmente definidas se consideran legítimo y utilizan a menudo suficiente para no imponer el tipo de construcción se muestra arriba? Si este es el caso, ¿puedes explicarme por qué los patrones no exhaustivos son útiles / legítima?
¿Fue útil?

Solución

Hay casos en que no le importa que una coincidencia de patrón no es exhaustiva. Por ejemplo, si bien esto podría no ser la óptima implementación, no creo que ayudaría si no se compila:

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

Que esto no es exhaustiva (los números negativos no encaja con ningún caso) realmente no importa para el uso habitual de la función factorial.

También puede ser que no sea generalmente posible decidir por el compilador si una comparación de patrones es exhaustiva:

mod2 :: Integer -> Integer
mod2 n | even n = 0
mod2 n | odd n  = 1

Aquí todos los casos debe ser cubierto, pero el compilador probablemente no puede detectarlo. Dado que los guardias podían ser arbitrariamente compleja, el compilador no siempre puede decidir si los patrones son exhaustivos. Por supuesto, este ejemplo mejor sería escrito con otherwise, pero creo que también se debe compilar en su forma actual.

Otros consejos

Se puede utilizar para convertir -Werror advertencias en errores. No sé si se puede convertir advertencias patrones sólo la no exhaustivos en errores, lo siento!

En cuanto a la tercera parte de su pregunta:

A veces escribir una serie de funciones que tienden a trabajar estrechamente juntos y tienen propiedades que no se puede expresar fácilmente en Haskell. Al menos algunas de estas funciones tienden a tener patrones no exhaustivos, por lo general los consumidores '. Esto viene a colación, por ejemplo, en las funciones que son 'una especie de' inversas entre sí.

ejemplo de juguete A:

duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : (duplicate xs)

removeDuplicates :: Eq a => [a] -> [a]
removeDuplicates [] = []
removeDuplicates (x:y:xs) | x == y = x : removeDuplicates xs

Ahora que es bastante fácil ver que removeDuplicates (duplicate as) es igual a as (siempre que el tipo de elemento está en Eq), pero en general, se colgará duplicate (removeDuplicates bs), porque hay un número impar de elementos o 2 elementos consecutivos diferir. Si no se estrella, es porque bs fue producido por (o podría haber sido producido por) duplicate en el primer lugar !.

Así que tenemos las siguientes leyes (no válido Haskell):

removeDuplicates . duplicate == id
duplicate . removeDuplicates == id (for values in the range of duplicate)

Ahora, si desea evitar que los patrones no exhaustivos aquí, usted podría hacer removeDuplicates retorno Maybe [a], o añadir mensajes de error para los casos que faltan. Incluso se podría hacer algo en la línea de

newtype DuplicatedList a = DuplicatedList [a]

duplicate :: [a] -> DuplicatedList a
removeDuplicates :: Eq a => DuplicatedList a -> [a]
-- implementations omitted

Todo esto es necesario, porque no se puede expresar con facilidad 'de ser una lista de longitud, incluso, con pares consecutivos de elementos en igualdad de condiciones' en el sistema de tipos de Haskell (a menos que seas Oleg:)

Pero si no exporta removeDuplicates Creo que es perfectamente apropiado el uso de patrones no exhaustivos aquí. Tan pronto como lo hace la exportación que, si no se pierden control sobre los insumos y tendrá que hacer frente a los casos perdidos!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top