Estou tentando aprender Haskell por meio do advento do código (eu sei, já estamos no fim da temporada), mas estou encontrando problemas de recuo que não entendo, apesar de verificar o que acredito serem as seções relevantes em haskell.org ou wikibooks .
Especificamente, ao recuar minha função auxiliar interna, o haskell enviará um erro de análise se eu recuar em 4 ou menos espaços (sem contar os 4 espaços de recuo do bloco principal), mas funcionará se recuar em pelo menos 5 espaços adicionais. Então, preciso recuar meu let ... em pelo menos 9 espaços. No entanto, recuar o bloco principal em apenas 4 espaços e não 5 parece funcionar bem, e não entendo a diferença.
Então isso funciona:
solvePart1 :: String -> IO ()
solvePart1 input = do
let parsedInput = map (map read . words) . lines $ input :: [[Int]]
let validateReport report =
let differences = zipWith (-) report (tail report)
in all (\d -> d >= 1 && d <= 3) differences || all (\d -> d <= -1 && d >= -3) differences
let areReportsValid = map validateReport parsedInput
let validReportsCount = sum $ map fromEnum areReportsValid
putStrLn $ "Day 2, Part 1: " ++ show validReportsCount
mas isso não :
solvePart1 :: String -> IO ()
solvePart1 input = do
let parsedInput = map (map read . words) . lines $ input :: [[Int]]
let validateReport report =
let differences = zipWith (-) report (tail report)
in all (\d -> d >= 1 && d <= 3) differences || all (\d -> d <= -1 && d >= -3) differences
let areReportsValid = map validateReport parsedInput
let validReportsCount = sum $ map fromEnum areReportsValid
putStrLn $ "Day 2, Part 1: " ++ show validReportsCount
O problema não está relacionado à sintaxe do vs let ..., pois reescrever a função interna como um bloco do não altera o problema: 5 espaços ainda são necessários.
(Estou usando vscode como editor e construindo com stack caso seja relevante)
Até certo ponto, é o mesmo que:
contra:
O item precisa estar uma coluna à direita do início do identificador que define o escopo. Então o
let
em si não conta, de fato, por exemplo, o mesmo também não funciona:Funciona se houver
let
uma coluna a mais à direita do quex
:Dito isso, normalmente você não usa muito
let
s em umdo
bloco, mas trabalha com uma função sem umdo
bloco, como:e então resolva com:
Isso é algo que frequentemente confunde os novatos em Haskell. A
let
palavra-chave é um arauto de layout comodo
,where
, eof
(como emcase
…of
), o que significa que ela inicia um bloco quando não é seguida por uma chave de abertura. A primeira coisa depois da palavra-chave determina a margem esquerda do bloco. Se preferir, você sempre pode colocar uma nova linha e recuo depois de uma palavra-chave de layout, então você não precisará alinhar nada. E quando você tem váriaslet
ligações, você pode mesclá-las em um únicolet
bloco.Tente usar chaves e ponto e vírgula explicitamente em um programa. Isso o deixará familiarizado com o local onde a regra de layout os insere.