Definir una función por ecuaciones con diferentes números de argumentos

Hoy noté que tal definición

safeDivide x 0 = x safeDivide = (/) 

no es posible. Solo tengo curiosidad por saber cuál es la (buena) razón detrás de esto. Debe haber uno muy bueno (es Haskell después de todo :)).

Nota: No estoy buscando sugerencias para implementaciones alternativas al código anterior, es un ejemplo simple para demostrar mi punto.

Creo que es principalmente por coherencia, por lo que todas las cláusulas se pueden leer de la misma manera, por así decirlo; es decir, cada RHS está en la misma posición en el tipo de función. Creo que enmascararía bastantes errores tontos si permitieras esto también.

También hay una ligera peculiaridad semántica: digamos que el comstackdor completó estas cláusulas para tener el mismo número de patrones que las otras cláusulas; es decir, su ejemplo se convertiría

 safeDivide x 0 = x safeDivide xy = (/) xy 

Ahora considere si la segunda línea en cambio había sido safeDivide = undefined ; en ausencia de la cláusula previa, safeDivide sería , pero gracias a la expansión eta realizada aquí, es \xy -> if y == 0 then x else ⊥ – entonces safeDivide = undefined realmente no define safeDivide como ! Esto parece lo suficientemente confuso como para justificar la prohibición de tales cláusulas, IMO.

El significado de una función con varias cláusulas se define mediante el estándar Haskell (sección 4.4.3.1) a través de la traducción a una lambda y statement de case :

 fn pat1a pat1b = r1 fn pat2a pat2b = r2 

se convierte

 fn = \ab -> case (a,b) of (pat1a, pat1b) -> r1 (pat2a, pat2b) -> r2 

Esto es para que la forma de hacer las cosas de la definición de función / caso sea agradable y coherente, y el significado de cada una no se especifique de manera redundante y confusa.

Esta traducción solo tiene sentido cuando cada cláusula tiene el mismo número de argumentos. Por supuesto, podría haber reglas adicionales para arreglar eso, pero complicarían la traducción con poca ganancia, ya que probablemente no quieras definir cosas así de todos modos, por el bien de tus lectores.

Haskell lo hace de esta manera porque lo hicieron sus predecesores (como LML y Miranda). No hay razón técnica para que tenga que ser así; las ecuaciones con menos argumentos podrían ser eta expandidas. Pero tener una cantidad diferente de argumentos para diferentes ecuaciones es probablemente un error tipográfico en lugar de intencional, por lo que en este caso prohibimos algo sensible y raro para obtener mejores informes de errores en el caso común.