haskell ghci

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> :}