Hennes
Hennes

Reputation: 1370

How can I execute IO commands repeatedly in Haskell?

I have a function blabla in Haskell which takes an Int and returns a string:

blabla :: Int -> [Char]

I want to run that method repeatedly in a for-loop, something like this:

for i := 1 to 25 do begin
    write(i);
    write(": ");
    writeln(blabla(i));
end;

Does haskell have a for loop feature?

Upvotes: 11

Views: 1529

Answers (4)

Aadit M Shah
Aadit M Shah

Reputation: 74204

There's a forM_ function in the Control.Monad module which is similar to a for loop in imperative programming languages:

import Control.Monad (forM_)

blabla :: Int -> String
blabla = show

main = forM_ [1..25] $ \i -> do
    putStr   (show i)
    putStr   ": "
    putStrLn (blabla i)

However, I would advise you to stay away from such imperative style code. For example, the same code can be written more succinctly as:

import Control.Monad (mapM_)

blabla :: Int -> String
blabla = show

main = mapM_ (\i -> putStrLn $ show i ++ ": " ++ blabla i) [1..25]

Hope that helps.

Upvotes: 15

Hennes
Hennes

Reputation: 1370

Upon drinking a cup of tea I got the best result, I think:

blablaResults = map (\x -> show x ++ ":" ++ blabla x) [0..25]

main = putStrLn $ unlines blablaResults

Upvotes: 7

You're still thinking in a procedural fashion. Try to think in terms of lists, rather than in terms of loops.

Then what you want is a list like this: [1,f(1),2,f(2),3,f(3)...,n,f(n)]

This is where map enters the picture. If you had a function f and wanted to apply it to a list [1,2,3...,n], you use map f [1..n].

What you want is a function that takes a number i and applies a function f to it,then responds with [i,f(i)] or perhaps a tuple (i,f(i)). So you create this function and map it to your list.

And, of course, you need to create that initial list to operate on - that list from [1..n].

Another approach is to use a list comprehension:

forloop n = [(x,f x)|x <- [1..n] ]

(Note: I have no Haskell compiler with me right now, so I need to verify that last part later. I believe it should work as presented).

Upvotes: 2

Hennes
Hennes

Reputation: 1370

I think, I got it by myself:

blablaOutput :: [Int] -> IO()
blablaOutput (x:xs) = do 
  putStrLn (blabla x)
  blablaOutput xs
blablaOutput _ = putStrLn "That's all, folks!"  

main = blablaOutput [0..25]

Certainly not very functional in means of functional programming, but it works.

Upvotes: 0

Related Questions