J'ai des problèmes pour entrer des commandes multilignes dans ghci.
Le code de 2 lignes suivant fonctionne à partir d'un fichier:
addTwo :: Int -> Int -> Int
addTwo x y = x + y
Mais quand j'entre dans ghci, j'obtiens une erreur:
<interactive>:1:1: error:
Variable not in scope: addTwo :: Int -> Int -> Int
J'ai également essayé de mettre le code à l'intérieur :{ ... :}
, mais ils ne fonctionnent pas non plus pour cet exemple, car il s'agit simplement d'ajouter les lignes sur une seule ligne, ce qui ne devrait pas être le cas.
J'utilise WinGHCi, version 2011.2.0.1
Réponses:
La plupart du temps, vous pouvez vous fier à l'inférence de type pour élaborer une signature à votre place. Dans votre exemple, ce qui suit est suffisant:
Si vous voulez vraiment une définition avec une signature de type, ou si votre définition s'étend sur plusieurs lignes, vous pouvez le faire dans ghci:
Notez que vous pouvez également presser ceci sur une ligne:
Vous pouvez en savoir plus sur l'interaction avec ghci dans l' évaluation interactive dans la section invite de la documentation.
la source
let
commence un bloc; les entrées d'un bloc sont regroupées par indentation; et le premier caractère non blanc d'un bloc définit l'indentation par laquelle ils sont regroupés. Étant donné que le premier caractère non blanc dans lelet
bloc ci-dessus est lea
deaddTwo
, toutes les lignes du bloc doivent être indentées exactement aussi profondément que celaa
.Résolvez ce problème en lançant GHCI et en tapant
:set +m
:Boom.
Ce qui se passe ici (et je parle principalement à vous , personne cherchant de l'aide sur Google tout en travaillant sur Learn You A Haskell ), c'est que GHCI est un environnement interactif dans lequel vous modifiez les liaisons des noms de fonctions à la volée. Vous devez envelopper vos définitions de fonction dans un
let
bloc, pour que Haskell sache que vous êtes sur le point de définir quelque chose. Le:set +m
truc est un raccourci pour le code multiligne:{
:}
construction de .Les espaces blancs sont également importants dans les blocs, vous devez donc indenter votre définition de fonction après votre définition de type de quatre espaces pour tenir compte des quatre espaces dans
let
.la source
echo ':set +m' >> ~/.ghci
pour rendre ce paramètre persistant.let
seul sur la première ligne, alors tout le reste n'a pas du tout besoin d'être en retrait. là où l'espace blanc compte vraiment, il ne doit pas y avoir d'espaces de fin sur vos lignes. Les espaces de fin comptent comme une entrée supplémentaire et coupent le bloc multiligne.Utilisez
let
:la source
À partir de la version 8.0.1 de GHCI , il
let
n'est plus nécessaire de définir des fonctions sur le REPL.Cela devrait donc bien fonctionner pour vous:
L'inférence de type de Haskell fournit un typage généralisé qui fonctionne également pour les flottants:
Si vous devez fournir votre propre typage, il semble que vous devrez utiliser
let
combiné avec une entrée multiligne (à utiliser:set +m
pour activer l'entrée multiligne dans GHCI):Mais vous obtiendrez des erreurs si vous essayez de passer autre chose que un à
Int
cause de votre typage non polymorphe:la source
Pour développer la réponse d'Aaron Hall , dans la version GHCi 8.4.4 au moins, vous n'avez pas besoin d'utiliser
let
avec les déclarations de type si vous utilisez le:{
:}
style. Cela signifie que vous n'avez pas à vous soucier d'ajouter l'indentation de 4 espaces sur chaque ligne suivante à prendre en comptelet
, ce qui rend les fonctions plus longues beaucoup plus faciles à taper ou, dans de nombreux cas, à copier-coller (car la source d'origine n'aura probablement pas l'indentation correcte):Mettre à jour
Comme alternative, vous pouvez activer le mode d'entrée multiligne avec
:set +m
, puis tapezlet
seul, appuyer sur Entrée, puis coller les définitions sans indentation requise.Cependant, cela ne semble pas fonctionner avec certains blocs de code, tels que:
Mais la
:{
,:}
fait technique.la source
:{
, puis sur la ligne suivantelet
seule, puis coller vos définitions sans aucune indentation supplémentaire, puis fermer avec:}
. :) et avec le mode d'entrée multiligne set (:set +m
), vous n'avez même pas besoin des commandes d'accolades tant qu'il n'y a pas d'espaces de fin sur les lignes de code.:set +m
vous pouvez simplement utiliserlet
sur sa propre ligne? Donc vous pouvez - c'est cool. Je vous remercie.let
puis la nouvelle ligne ne fonctionne pas. Voir ma modification.