Próbuję nauczyć się pisać programy Haskella. Nie mogę odczytać wejścia n wierszy.
Wejście jest
N
A b (<----- n razy)
Gdzie n, a, b to liczby.
Próbowałem
input = []
readString 0 = return()
readString n =
do
z <- getLine
z:input
readString (n-1)
main = do
n <- getLine
readString n
Co powoduje błędy. Jak poprawnie zapętlić odczyt w Haskell?
1 odpowiedź
Haskell jest niezmienny: kiedy już napiszesz
input = []
Wtedy input
jest []
na wieki wieków, amen. Możesz użyć tej samej techniki, której użyłeś do uzyskania „zmieniającej się” wartości n
, aby uzyskać „zmieniającą się” wartość input
, czyli przekazać ją jako argument do readString
:
readString 0 input = return input
readString n input = do
z <- getLine
readString (n-1) (z:input)
Jeśli to zrobisz, odkryjesz, że linie, które wprowadzisz, są umieszczane w input
, zaczynając od końca - więc wychodzą w odwrotnej kolejności! (Gdyby Twój fragment kodu zadziałał, również zachowywałby się w ten sposób.) Jednym z łatwych rozwiązań byłaby zmiana przypadku podstawowego:
readString 0 input = return (reverse input)
Bardziej idiomatycznym rozwiązaniem byłoby całkowite wyeliminowanie argumentu, po prostu zwracanie rzeczy we właściwej kolejności:
readString 0 = return []
readString n = do
z <- getLine
zs <- readString (n-1)
return (z:zs)
Gdy oswoisz się ze standardową biblioteką, możesz najpierw przejść do:
readString 0 = return []
readString n = liftA2 (:) getLine (readString (n-1))
A następnie do całkowitego pominięcia definicji readString
na rzecz przepisania main
:
main = do
n <- readLn
replicateM n getLine
Podobne pytania
Nowe pytania
loops
Pętle to rodzaj struktury przepływu sterowania w programowaniu, w którym seria instrukcji może być wykonywana wielokrotnie, aż do spełnienia określonego warunku.