eenvoudige Haskell-lus

Ik ben net begonnen met het leren van Haskell, maar de afwezigheid van loops is momenteel enorm frustrerend. Ik heb ontdekt hoe ik loops voor functies kan schrijven. Mijn probleem is echter dat ik enkele resultaten wil weergeven terwijl ik de lus herhaal. Het lijkt erop dat ik debug moet gebruiken om deze eenvoudige taak uit te voeren.

Dus op dit moment zou ik graag een voorbeeld waarderen van hoe je een string 10 keer in de hoofdstructuur kunt afdrukken.

Met andere woorden, ik wil dit 10 keer doen:

main = do  
    putStrLn "a string" 

Bedankt. Ik denk dat dit zeer verhelderend zal zijn voor mijn taak.


Antwoord 1, autoriteit 100%

Je zou een recursieve functie kunnen definiëren die n keer “een string” afdrukt (n is de parameter van de functie), als volgt:

printStringNTimes 0 = return ()
printStringNTimes n =
 do
  putStrLn "a string"
  printStringNTimes (n-1)
main = printStringNTimes 10

Een wat algemenere benadering zou zijn om een functie te definiëren die elke IO-actie n keer herhaalt:

repeatNTimes 0 _ = return ()
repeatNTimes n action =
 do
  action
  repeatNTimes (n-1) action
main = repeatNTimes 10 (putStrLn "a string")

De bovenstaande functie bestaat al in Control.Monadonder de naam replicateM_.


Antwoord 2, autoriteit 66%

Nou, de IO van Haskell is een beetje lastig als je net begint, omdat het gebaseerd is op monaden.

Uw probleem heeft echter een eenvoudige oplossing:

main = replicateM_ 10 $ putStrLn "a string"

Dit gebruikt de combinator replicateM_van Control.Monad

Het heeft veel handige functies voor het samenstellen en uitvoeren van monadische acties.


Antwoord 3, autoriteit 5%

Ik ben ook een beginner van Haskell en ik heb een oplossing die minder elegant is en toch pragmatisch bruikbaar.

main = do 
    putStr result
    where
        string = "a string"
        result = concat [string ++ "\n" | i <- [1,2..10]]

Dus hier hebben we een lijst gedefinieerd, waarvan de elementen de tekenreeksen zijn die u wilt afdrukken, gevolgd door een nieuw regelteken.


Antwoord 4, autoriteit 2%

Ik denk dat de meest dwingende vorm van het doen van een for-lus is:

for list action = mapM_ action list
main :: IO Int
main = do
    for [0..10] (\ i -> do
        print(i^2)
        )
    return 0

Dit lijkt voor mij eigenlijk op C-code.


Antwoord 5, autoriteit 2%

Als je zoiets doet, kun je een specifieke functie herhalen, waardoor deze meer herbruikbaar wordt (in plaats van het uit te schrijven voor elk nieuw ding dat je wilt herhalen).

loop :: Int -> (IO()) -> IO()
loop 0 _ = return ()
loop n f =
 do
  f
  loop (n - 1) f

Voorbeelden:

main = do
 loop 5 (do
  putStr "hello "
  putStrLn "there")
main = do
 loop 3 (do
  loop 4 (putStrLn "Hi")
  putStrLn ""
  )

Other episodes