I have a problem, user inputs number m (meaning matrix has m-rows, m-columns), then the matrix is read from stdin. I want to transpose the matrix and then output the matrix back on the screen in the same format.
for example:
Main> main
3
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9
Anyway, I got somewhere in the middle, but i dont know how to parse the [[Int]] back to IO, so it can be print on the screen.
here is my code:
import Control.Monad (replicateM)
transpose :: [[a]]->[[a]]
transpose ([]:_) = []
transpose x = (map head x) : transpose (map tail x)
readMany :: Read a => IO [a]
readMany = fmap (map read . words) getLine
parse :: IO ([[Int]])
parse = do
[m] <- readMany
xss <- replicateM m readMany
let matrix = transpose xss
return (matrix)
main :: IO ()
main = do
parse
?? --
print ??
First, you have to extract the value you parse:
Now, what’s the type of
print?Well,
[[Int]]is an instance ofShow, so we can treat print as a specialisation of its type:So, in fact, it’s as simple as filling in the list we want to print in place of the
???:However, this prints the data out in the same way that GHCi does. If you want to print the data out in a custom format, you want:
Let’s say you write a function to format the matrix the way you want into a string:
This makes the complete program:
The difference between
foo <- barandlet foo = baris that the former extracts the result of an IO computation, while the latter just gives a name to a value.So basically, the answer is that you don’t need to put anything into IO to do this, since all the functions that create IO actions to do things like print strings out take pure values. This doesn’t make them limited to printing the results of completely pure computations, however, since you can extract values from previous IO computations, and then feed them in to the printing functions as pure values. (In fact, this is the essence of monads, and why Haskell uses them to model IO in the first place!)