Search code examples
haskellpascals-triangle

Printing Pascal's triangle in Haskell


I just started learning Haskell, and have been doing a few problems online. Most of the times, I can figure out the solution but I am unable to print it out in the output format that is expected.

For example, I tried doing a Pascal's triangle program. I found out how to generate Pascal's Triangle as a list of lists of Ints, but I cant figure out how to print it.

Here is my code.

import Data.List
pascal n = map liner [0..n]
    where liner x = map (comb x) [0..x]

comb n 0 = 1
comb 0 r = 0
comb n r = comb (n-1) (r-1) * n `div` r 

main = do
    order <- getLine
    let output = pascal . (read :: String -> Int) $ order
    print output 

Currently, the output is like

[[1],[1,1],[1,2,1],[1,3,3,1]...

I want to print it in the form

1
1 1
1 2 1
1 3 3 1
...

How do I do this? I have tried using things like mapM_ or intercalate " ", with no luck. I'm not into monads yet so I don't understand how mapM works.


Solution

  • There are several different ways to do this, but the most straight forward (IMO) is the following.

    putStrLn $ intercalate "\n" $ map (intercalate " " . map show) output
    

    This first converts all of the numbers in the list into strings (using show). Then it converts the innermost lists into strings, where each element is separated by spaces (using intercalate " "). Then it converts the outermost list into a string where each element is separated by a newline (using intercalate "\n"). And finally, it pushes the resulting string onto stdout. Replace the last line of your main with this and it should do what you want.

    EDIT: As Yakym mentioned in his answer, intercalate " " and intercalate "\n" can be replaced with unwords and unlines, making the code above a little more concise (it also removes the need for the import of Data.List).

    putStr $ unlines $ map (unwords . map show) output
    

    I changed putStrLn to putStr because unlines automatically adds a newline to the end of the output.