you tutorial online learn descargar company book haskell functional-programming

tutorial - learn you a haskell pdf



¿Qué son los "patrones n+k" y por qué están prohibidos en Haskell 2010? (2)

Al leer la entrada de Wikipedia en Haskell 2010 me encontré con esto:

-- using only prefix notation and n+k-patterns (no longer allowed in Haskell 2010) factorial 0 = 1 factorial (n+1) = (*) (n+1) (factorial n)

¿Qué quieren decir con "patrones n + k"? Supongo que es la segunda línea, pero no entiendo qué podría estar mal con eso. ¿Alguien podría explicar cuál es el problema allí? ¿Por qué no se permiten estos patrones de n + k en Haskell 2010?


¿Qué son los patrones n + k? Eche un vistazo a esto:

$ ghci GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> let f 0 = 0 ; f (n+5) = n Prelude> :t f f :: (Integral t) => t -> t Prelude> f 0 0 Prelude> f 1 *** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f Prelude> f 2 *** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f Prelude> f 3 *** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f Prelude> f 4 *** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f Prelude> f 5 0 Prelude> f 6 1

Básicamente son un caso extremadamente especial en la coincidencia de patrones que solo funciona en números y que sí ... bueno, seamos educados y lo llamemos "cosas inesperadas" para esos números.

Aquí tengo una función f que tiene dos cláusulas. La primera cláusula coincide con 0 y solo con 0 . La segunda cláusula coincide con cualquier valor de tipo Integral cuyo valor sea 5 o mayor. El nombre encuadernado ( n , en este caso) tiene un valor igual al número que pasaste en menos 5. En cuanto a por qué se eliminaron de Haskell 2010, espero que puedas ver el motivo ahora con un poco de pensamiento. (Sugerencia: considere el "principio de la menor sorpresa" y cómo puede aplicarse o no aquí).

Editado para agregar:

Una pregunta natural que surge ahora que estos constructos están prohibidos es "¿qué usas para reemplazarlos?"

$ ghci GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> let f 0 = 0 ; f n | n >= 5 = n - 5 Prelude> :t f f :: (Num t, Ord t) => t -> t Prelude> f 0 0 Prelude> f 1 *** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f Prelude> f 2 *** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f Prelude> f 3 *** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f Prelude> f 4 *** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f Prelude> f 5 0 Prelude> f 6 1

Notará por las declaraciones de tipo que estas no son precisamente iguales, pero el uso de un guardia es "lo suficientemente igual". El uso del n-5 en la expresión puede ser tedioso y propenso a errores en cualquier código que lo use en más de un lugar. La respuesta sería usar una cláusula where en la línea de esto:

Prelude> let f 0 = 0 ; f n | n >= 5 = n'' where n'' = n - 5 Prelude> :t f f :: (Num t, Ord t) => t -> t Prelude> f 0 0 Prelude> f 5 0 Prelude> f 6 1

La cláusula where permite usar la expresión calculada en múltiples lugares sin riesgo de errores. Todavía existe la molestia de tener que editar el valor del borde (5 en este caso) en dos ubicaciones separadas en la definición de la función, pero personalmente creo que este es un pequeño precio a pagar por el aumento en la comprensión cognitiva.

Editado adicionalmente para agregar:

Si prefiere let expresiones sobre cláusulas where , esta es una alternativa:

Prelude> let f 0 = 0 ; f n | n >= 5 = let n'' = n - 5 in n'' Prelude> :t f f :: (Num t, Ord t) => t -> t Prelude> f 0 0 Prelude> f 5 0

Y eso es. Estoy realmente hecho ahora.


El enlace proporcionado por Trinithis es correcto; Los patrones n + k ya no están incluidos en la especificación Haskell.

Para obtener más información general sobre los patrones n + k en general, desplácese aproximadamente 3 / 5ths del camino hacia abajo en esta página en la coincidencia de patrones , o consulte esta breve post .