haskell - Definición de funciones por casos especiales en GHCi
(2)
Para usar su definición en GHCi exactamente como la escribió (es decir, con múltiples ecuaciones en líneas separadas), debe usar la entrada de varias líneas en GHCi a través de los delimitadores:
:{
y
:}
:
GHCi> :{
GHCi| foo 0 = print 999
GHCi| foo n = print n
GHCi| :}
GHCi> foo 0
999
Una alternativa sería utilizar entradas multilínea para el resto de su sesión con la opción
+m
.
Sin embargo, en este caso, también necesita un permiso explícito, ya que sin él GHCi no descubrirá que desea continuar con la definición:
GHCi> :set +m
GHCi> let foo 0 = print 999
GHCi| foo n = print n
GHCi|
GHCi> foo 0
999
(Puede desactivar
+m
con
:unset +m
.)
Otra posibilidad es evitar por completo los saltos de línea y usar llaves explícitas y punto y coma:
GHCi> foo 0 = print 999; foo n = print n
GHCi> foo 0
999
Entre las opciones multilínea, personalmente prefiero los delimitadores explícitos sobre
+m
, ya que requiere menos cambios con respecto a cómo usualmente expreso mis definiciones, y es más probable que funcione de inmediato si pego el código desde otro lugar.
En cuanto a por qué su forma de ingresar no funcionó, fue porque, a menos que use una entrada multilínea, los enlaces al mismo nombre en líneas GHCi separadas se sombrean entre sí:
GHCi> x = 3
GHCi> x = 4
GHCi> x
4
Esto parece menos sorprendente si notamos que obtenemos el mismo comportamiento de una cadena de expresiones
let
:
GHCi> let x = 3 in let x = 4 in x
4
De un tutorial Haskell:
Podemos escribir funciones en enteros por casos.
-- Compute the sum of the integers from 1 to n.
sumtorial :: Integer -> Integer
sumtorial 0 = 0
sumtorial n = n + sumtorial (n-1)
Sin embargo, esto es lo que sucede cuando lo intento:
$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> foo 0 = print 999
Prelude> foo n = print n
Prelude> foo 0
0
¿Qué me estoy perdiendo?
ghci es una herramienta interactiva y, como tal, permite redefinir una función cuando ya está definida.
En su caso, no lo ve como una definición de función de dos líneas, sino como dos intentos de definirla.
Entonces
fn = print n
anula
f 0 = print 999
lugar de completarlo.
Para ingresar una declaración de varias líneas en ghci hay una sintaxis especial. Necesitas hacer
Prelude> :{
Prelude> let foo 0 = print 999
Prelude> foo n = print n
Prelude> :}