2010-05-17 20 views
130

Estoy tratando de definir cualquier función simple que abarca varias líneas en ghci, tome la siguiente como un ejemplo:¿Cómo se define una función en ghci en múltiples líneas?

let abs n | n >= 0 = n 
      | otherwise = -n 

Hasta ahora he intentado presionar Enter después de la primera línea:

Prelude> let abs n | n >= 0 = n 
Prelude>   | otherwise = -n 
<interactive>:1:0: parse error on input `|' 

también he intentado utilizar los comandos y :{:} pero no obtienen el momento:

Prelude> :{ 
unknown command ':{' 
use :? for help. 

estoy usando G HC Interactive versión 6.6 para Haskell 98 en Linux, ¿qué me estoy perdiendo?

+19

Actualice su instalación de GHC. ¡GHC 6.6 tiene casi 5 años! Las últimas versiones de Haskell están aquí: http://haskell.org/platform –

+0

posible duplicado de [comandos de varias líneas en GHCi] (http://stackoverflow.com/questions/8443035/multi-line-commands-in- ghci) – Mark

+0

@Mark Este OP ya probó las soluciones a ese problema. Este problema se debe a un ghci desactualizado, no a la falta de conocimiento sobre qué hacer. Solución aquí: actualización. Solución allí: use ': {', ':}'. – AndrewC

Respuesta

112

para los guardias (como el ejemplo), sólo puede poner a todos en una sola línea y funciona (guardias no se preocupan por el espaciamiento)

let abs n | n >= 0 = n | otherwise = -n 

si desea escribir su función con múltiples definiciones que el ajuste de patrones en los argumentos, así:

fact 0 = 1 
fact n = n * fact (n-1) 

allí tendría que utilizar llaves con punto y coma que separa las definiciones

let { fact 0 = 1 ; fact n = n * fact (n-1) } 
7

Si no desea actualizar GHC sólo para :{ y :}, tendrá que escribir en una sola línea:

> let abs' n | n >= 0 = n | otherwise = -n 

I' m no conoce ninguna definición única en Haskell que debe escribir en múltiples líneas. Lo anterior trabaja de hecho en GHCi:

> :t abs' 
abs' :: (Num a, Ord a) => a -> a 

Para otras expresiones, tales como do bloques, tendrá que utilizar la sintaxis no diseño con los apoyos y punto y coma (rizado EuGH).

43

Dan es correcta, pero :{:} y debe aparecer cada uno en su propia línea:

> :{ 
> let foo a b = a + 
>   b 
> :} 
> :t foo 
foo :: (Num a) => a -> a -> a 

Esto también interactúa con la regla de diseño, por lo que durante su utilización notación podría ser más fácil de usar aparatos ortopédicos y semi dos puntos explícitamente Por ejemplo, esta definición falla:

> :{ 
| let prRev = do 
| inp <- getLine 
| putStrLn $ reverse inp 
| :} 
<interactive>:1:18: 
    The last statement in a 'do' construct must be an expression 

Pero funciona cuando se añaden los apoyos y puntos y comas:

> :{ 
| let prRev = do { 
| inp <- getLine; 
| putStrLn $ reverse inp; 
| } 
| :} 
> :t prRev 
prRev :: IO() 

Esto sólo es realmente importa al pegar las definiciones de un archivo, donde la sangría podría cambiar.

+0

Esto no funciona si tiene una línea que termina en '=' (con la siguiente definición en la siguiente línea), al menos en la versión 7.6.3. – AdamC

+0

Quizás esto falla, porque la segunda y la tercera línea de la let no están suficientemente sangradas ...? (Dos espacios más). – Evi1M4chine

195

GHCi ahora tiene un modo de entrada multilínea, habilitado con: set + m.Por ejemplo,

Prelude> :set +m 
Prelude> let fac 0 = 1 
Prelude|  fac n = n * fac (n-1) 
Prelude| 
Prelude> fac 10 
3628800 
+29

Configurar el modo multilínea hace que 'ghci' se comporte de manera similar al intérprete de Python en este aspecto. ¡Muy conveniente! De hecho, puede crear un archivo '.ghci' en su directorio de inicio en el que ponga': set + m' y el modo multiline se convertirá en el predeterminado cada vez que inicie 'ghci'! – kqr

+2

Esto es realmente increíble. Pero me he dado cuenta de que cuando configuro mi prompt usando ': set prompt" λ "' las líneas continuas dicen 'Prelude' en lugar de' λ'. ¿Alguna forma de evitar esto? – abhillman

+2

Consulte aquí para ver el parche para definir un nuevo mensaje de continuación https://ghc.haskell.org/trac/ghc/ticket/7509#no1 – karakfa

Cuestiones relacionadas