TurtleTread
TurtleTread

Reputation: 1314

simple Haskell loop

I just started learning Haskell, but the absence of loops is infinitely frustrating right now. I figured out how to write loops for functions. My problem, however, is that I want to output some results while iterating the loop. It seems that I have to use debug to perform this simple task.

So right now I would just appreciate an example of how to print out a string 10 times in the main structure.

In other words, I want to do this 10 times:

main = do  
    putStrLn "a string" 

Thanks. I feel this will be very illuminating for my task.

Upvotes: 53

Views: 114545

Answers (6)

CHIYOI
CHIYOI

Reputation: 21

my solution:

n = 10
doSomething () = putStrLn "a string"
main = sequence (replicate n (doSomething()))
  • sequence: sequentially solve each IO a in a list
  • replicate n ele: build a list which repeats ele for n times, like take n (repeat ele)

Upvotes: 1

Doot
Doot

Reputation: 745

Doing something like to this allows you to loop a specific function, making it more reusable (instead of writing it out for each new thing you want to loop).

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

Examples:

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

Upvotes: 1

Tomás Vallotton
Tomás Vallotton

Reputation: 638

I think the most imperative looking form of doing a for loop is:

for list action = mapM_ action list

main :: IO Int
main = do
    for [0..10] (\ i -> do

        print(i^2)
        )
    return 0

This actually looks pretty much like C code to me.

Upvotes: 2

Enzhi Li
Enzhi Li

Reputation: 41

I am also a beginner of Haskell, and I have a solution that is less elegant and yet is pragmatically useful.

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

So here, we have defined a list, the elements of which are the strings that you want to print out followed by a new line character.

Upvotes: 4

daniel gratzer
daniel gratzer

Reputation: 53881

Well Haskell's IO is a bit tricky when you're just starting out since it's based on monads.

Your problem though has a simple solution:

main = replicateM_ 10 $ putStrLn "a string"

This is using the combinator replicateM_ from Control.Monad

It has lots of useful functions for composing and executing monadic actions.

Upvotes: 47

sepp2k
sepp2k

Reputation: 370162

You could define a recursive function that prints "a string" n times (n being the parameter of the function), like this:

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

main = printStringNTimes 10

A somewhat more general approach would be to define a function that repeats any IO action n times:

repeatNTimes 0 _ = return ()
repeatNTimes n action =
 do
  action
  repeatNTimes (n-1) action

main = repeatNTimes 10 (putStrLn "a string")

The above function already exists in Control.Monad under the name replicateM_.

Upvotes: 76

Related Questions