I want to show the content of lists with arbitrary types, one element per line, numbered starting at 1 like this :
String Example:
> bs "Hallo"
1. 'H'
2. 'a'
3. 'l'
4. 'l'
5. 'o'
Integer Example
> bs [5,6,1,2]
1. 5
2. 6
3. 1
4. 2
Tuples Example
> bs [(4,"Test"),(3,"Aye"),(5,"Fives")]
1. (4,"Test")
2. (3,"Ayes")
3. (4,"Fives)
I found this to be one solution:
bs' :: Show a => [a] -> Integer -> IO ()
bs' [] _ = return ()
bs' (x:xs) y = do
putStrLn $ (show y) ++ ". " ++ (show x)
bs' xs $ succ y
bs x = bs' x 1
As I am absolute beginner to Haskell I wonder what is the "best" way to solve this problem? Am I on the right trail or is that just plain "bad" Haskell.
How to output the Chars in the String example without the '' and still be able to output any type which has an instance of Show ?
I would like to know about other ways to solve this task, from different perspectives like: readability, efficiency, code reuse.
I also did it like this and found it even stranger (but somehow cool):
bs' :: Show a => [(Integer,a)] -> IO ()
bs' [] = return ()
bs' ((x1,x2):xs) = do
putStrLn $ (show x1) ++ ". " ++ (show x2)
bs' xs
bs x = bs' (zip [1..] x)
I have done about 25 years of imperative programming and being really interested in learning something new. At the same time if feels incredible "strange" to code in Haskell and I still can't imagine how a big project is done with this "crazy language from the moon" :)
EDIT: I wanna thank everybody. I choose one Answer because I have to but all are very helpful! I also want to say that the top solution I had was because "in the real problem" where that came from I had to skip some list elements and the numbering got wrong when using the zip approach. After reading all the answers I am pretty sure, that even then the solution is to first filter the list and then zip map the output function.