Comment définir une fonction dans ghci sur plusieurs lignes?

J’essaie de définir une fonction simple qui couvre plusieurs lignes dans ghci, prenons l’exemple suivant:

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

Jusqu’à présent, j’ai essayé d’appuyer sur Entrée après la première ligne:

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

J’ai aussi essayé d’utiliser les commandes :{ et :} mais je ne vais pas loin:

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

J’utilise GHC Interactive version 6.6 pour Haskell 98 sous Linux, qu’est-ce qui me manque?

pour les gardes (comme votre exemple), vous pouvez simplement les mettre sur une seule ligne et cela fonctionne (les gardes ne se soucient pas de l’espacement)

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

Si vous vouliez écrire votre fonction avec plusieurs définitions, cela correspondrait aux arguments, comme ceci:

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

alors vous utiliseriez des accolades avec des points-virgules séparant les définitions

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

GHCi a maintenant un mode d’entrée multiligne, activé avec: set + m. Par exemple,

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

Dan a raison, mais :{ et :} doivent apparaître chacun sur leur propre ligne:

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

Cela interagit également avec la règle de mise en page, de sorte qu’en utilisant la notation de do, il peut être plus facile d’utiliser explicitement des accolades et des points-virgules. Par exemple, cette définition échoue:

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

Mais cela fonctionne quand des accolades et des points-virgules sont ajoutés:

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

Cela ne sera vraiment important que lorsque vous collez des définitions à partir d’un fichier, où l’indentation peut changer.

On dirait que :{ et :} sont une nouvelle fonctionnalité. Vous devrez peut-être mettre à niveau GHC.

Edit: confirmé, voir http://www.haskell.org/ghc/docs/6.8.2/html/users_guide/release-6-8-2.html

Si vous ne souhaitez pas mettre à niveau GHC uniquement pour :{ et :} , vous devez tout écrire sur une seule ligne:

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

Je ne connais aucune définition unique dans Haskell qui doit être écrite sur plusieurs lignes. Ce qui précède fonctionne bien dans GHCi:

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

Pour les autres expressions, telles que do blocs do , vous devez utiliser la syntaxe de non-présentation avec des accolades et des points-virgules (eugh).