I have a list of type [Int] which can only contain two values: 0 or 1.
Example : [0, 0, 1, 1, 0, 0]
I would like to iterate through this list and when the current element is a 0, print '_' and if it is a 1 print '*'.
For the previous list, here is the result on the standard output :
__**__
I think that I have to do something like that :
displayLine :: [Int] -> IO [Int]
displayLine (0 : xs) =
do
print '_'
-- next char
displayLine (1 : xs) =
do
print '*'
-- next char
How can I display a character and continue recursion with the next character?
You call displayLine with the tail of the list. But here the type will be IO (), not IO [Int] since the action does not return anything:
displayLine :: [Int] -> IO ()
displayLine (0 : xs) = do
print '_'
displayLine xs
displayLine (1 : xs) = do
print '*'
displayLine xs
You probably also want to use putChar :: Char -> IO () to print a single char, since print will call show and thus print a Char literal, and a new line.
This however duplicates logic. We can make use of mapM_ :: (Foldable f, Monad m) => (a -> m b) -> f a -> m () to perform a mapping where each element performs a monadic action:
displayLine :: [Int] -> IO ()
displayLine = mapM_ (putChar . f)
where f 0 = '_'
f 1 = '*'
For example:
Prelude> displayLine [0,1,1,0,1,0] >> putStrLn ""
_**_*_
The putStrLn "" at the end is used to start a new line after the characters have been printed.
The nice thing about do-notation is that the code usually looks just like it would in an imperative language (only better) : a couple of statements and a return at the end:
displayLine (0 : xs) = do
print '_'
ys <- displayLine xs -- ys will be identical to xs,
return (0:ys)
Don't forget to add a case for displayLine [], unless all of your lists are infinite....
BTW, do you really need to return anything, as the list is returned unchanged? If not, the type of displayLine could be [Int] -> IO () and the definition could be even simpler..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With