Estou tendo problemas ao inserir comandos de várias linhas no ghci.
O seguinte código de duas linhas funciona a partir de um arquivo:
addTwo :: Int -> Int -> Int
addTwo x y = x + y
Mas quando entro em ghci, recebo um erro:
<interactive>:1:1: error:
Variable not in scope: addTwo :: Int -> Int -> Int
Eu também tentei colocar o código dentro :{ ... :}
, mas eles também não estão funcionando neste exemplo, porque isso é apenas anexar as linhas em uma linha, o que não deve ser o caso.
Estou usando o WinGHCi, versão 2011.2.0.1
Respostas:
Na maioria das vezes, você pode confiar na inferência de tipo para elaborar uma assinatura para você. No seu exemplo, o seguinte é suficiente:
Se você realmente deseja uma definição com uma assinatura de tipo ou sua definição se estende por várias linhas, você pode fazer isso em ghci:
Observe que você também pode compactar isso em uma linha:
Você pode descobrir mais sobre como interagir com o ghci na avaliação interativa na seção de prompt da documentação.
fonte
let
inicia um bloco; as entradas em um bloco são agrupadas por recuo; e o primeiro caractere sem espaço em branco em um bloco define o recuo pelo qual eles são agrupados. Como o primeiro caractere que não é um espaço em branco nolet
bloco acima é oa
deaddTwo
, todas as linhas no bloco devem ser recuadas exatamente tão profundas quanto issoa
.Resolva esse problema iniciando o GHCI e digitando
:set +m
:Estrondo.
O que está acontecendo aqui (e eu estou falando principalmente com você , pesquisando em busca de ajuda enquanto trabalha no Learn You A Haskell ) é que o GHCI é um ambiente interativo no qual você altera as ligações dos nomes das funções em tempo real. Você precisa agrupar suas definições de função em um
let
bloco, para que Haskell saiba que você está prestes a definir alguma coisa. O:set +m
material é uma abreviação para a construção de:{
código de várias linhas:}
.O espaço em branco também é significativo em blocos, portanto, você deve recuar sua definição de função após a definição de tipo por quatro espaços para contabilizar os quatro espaços em
let
.fonte
echo ':set +m' >> ~/.ghci
para tornar essa configuração persistente.let
por si só na primeira linha, então todo o resto não precisa ser recuado. onde o espaço em branco realmente conta é que não deve haver espaços à direita em suas linhas. o espaço em branco à direita conta como um Enter extra e quebra o bloco de várias linhas.Use
let
:fonte
A partir do GHCI versão 8.0.1 ,
let
não é mais necessário definir funções no REPL.Portanto, isso deve funcionar bem para você:
A inferência de tipo de Haskell fornece digitação generalizada que também funciona para carros alegóricos:
Se você precisar fornecer sua própria digitação, parece que precisará usar
let
combinado com:set +m
a entrada de várias linhas (use para ativar a entrada de várias linhas no GHCI):Mas você receberá erros se tentar passar algo além de uma
Int
por causa da sua digitação não polimórfica:fonte
Para expandir a resposta de Aaron Hall , na versão GHCi 8.4.4, pelo menos, você não precisa usar as
let
declarações de tipo se usar o:{
:}
estilo. Isso significa que você não precisa se preocupar em adicionar a indentação de quatro espaços em cada linha subseqüente a ser consideradalet
, facilitando muito a digitação de funções mais longas ou, em muitos casos, copiar e colar (já que a fonte original provavelmente não terá o recuo correto):Atualizar
Como alternativa, você pode ativar o modo de entrada de várias linhas com
:set +m
e digitelet
por si próprio, pressionar Enter e colar definições sem recuo necessário.No entanto, isso não parece funcionar com alguns blocos de código, como:
Mas a
:{
,:}
técnica faz.fonte
:{
, em seguida, na próxima linhalet
, colar suas definições sem recuo adicional e fechar:}
. :) e com o modo de entrada de várias linhas definido (:set +m
), você nem precisou dos comandos de chaves, desde que não houvesse espaços à direita nas linhas de código.:set +m
você pode usar apenaslet
na sua própria linha? Então você pode - isso é legal. Obrigado.let
newline não funciona. Veja minha edição.