Sou novo em Haskell e tive uma tarefa de casa da universidade que compilava apenas tendo uma linha consistindo apenas de um único ponto e vírgula. Estou curioso, se esse é o comportamento pretendido e, se sim, por quê?
(Eu produzi linhas de código interessantes nos últimos dias que não estavam funcionando como esperado, cada uma era uma pequena palestra, por exemplo, --|
não era uma guarda comentada, mas um operador indefinido, etc.)
A única versão que consegui fazer funcionar é (código completo abaixo):
case input of {
... -- some other code
('0':xs) -> [(next Zero, rest)] where (next, rest) = readAll xs
;
... -- some other code
}
Gostaria de saber se é possível fazer isso sem uma linha composta por um único ponto e vírgula e por que os exemplos abaixo não funcionaram.
Eu tentei, por exemplo
('0':xs) -> [(next Zero, rest)] where (next, rest) = readAll xs;
('0':xs) -> [(next Zero, rest)] where (next, rest) = (readAll xs);
('0':xs) -> [(next Zero, rest)]
where
(next, rest) = (readAll xs);
mas todos eles levaram ao mesmo tipo de erro:
file.hs:19:8: error: parse error on input ‘(’
|
19 | ('1':xs) -> [(next One , rest)] where (next, rest) = readAll xs
| ^
Um trecho de código executável:
data BinaryDigit = Zero | One
data BinaryNumber = L BinaryDigit -- L: last digit
| E BinaryDigit BinaryNumber -- E: intermediate digit
instance Show BinaryNumber where
show (L Zero) = "0"
show (L One ) = "1"
show (E digit next) = show (L digit) ++ show next
instance Read BinaryNumber where
-- idea:
-- next item must be known to decide whether E or L constructor to use
-- create function that will be called on the next element and returns the right constructor,
-- with only one parameter, the current digit value, unset
readsPrec _ input = case input of {
('0':'0':xs) -> readsPrec 0 ('0':xs);
('0':'1':xs) -> readsPrec 0 ('1':xs);
('0':xs) -> [(next Zero, rest)] where (next, rest) = readAll xs
;
('1':xs) -> [(next One , rest)] where (next, rest) = readAll xs
;
otherwise -> [];
} where
readAll :: String -> (BinaryDigit -> BinaryNumber, String)
readAll ('0':xs) = ((`E` (next Zero)), rest) where (next, rest) = readAll xs
readAll ('1':xs) = ((`E` (next One )), rest) where (next, rest) = readAll xs
readAll str = (L, str)
main = putStrLn $ show (read "110" :: BinaryNumber)