188 votes

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

J'essaie de définir n'importe quelle 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
<interactive>:1:0: parse error on input `|'
 

J'ai également essayé d'utiliser les commandes :{ et :} mais je ne vais pas trop loin:

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

J'utilise GHC Interactive version 6.6 pour Haskell 98 sous Linux, que me manque-t-il?

294voto

karakfa Points 604

GHCi a maintenant un mode de saisie 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
 

139voto

newacct Points 42530

pour les gardes (comme dans votre exemple), vous pouvez simplement les mettre tous 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 voulez écrire votre fonction avec plusieurs définitions, ce modèle correspond 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) }
 

72voto

Justin Bailey Points 449

Dan est correct, mais :{ et :} chacun doit apparaître sur leur propre ligne:

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

Cette interagit également avec la mise en page de la règle, de sorte que lors de l'utilisation de do-la notation pourrait être plus facile d'utiliser des accolades et des points-virgules explicitement. Par exemple, cette définition ne fait pas:

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

Mais il fonctionne lorsque les accolades et les points-virgules sont ajoutés:

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

Cela ne sera vraiment d'importance lors du collage de définitions à partir d'un fichier, où les retraits sont susceptibles de changer.

21voto

Dan Points 6451

Il semble que :{ et :} soient une jolie 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

8voto

C. A. McCann Points 56834

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

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

Je ne connais aucune définition en Haskell qui doive ê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 les blocs do , vous devrez utiliser la syntaxe de non-présentation avec des accolades et des points-virgules (eugh).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X