Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print part of a list on a new line in Haskell

Tags:

list

haskell

This may be a silly question, but I'm very new to Haskell. (I just started using it a couple of hours ago actually.)

So my problem is that I have a list of 4 elements and I need to print two on one line and two on a new line.

Here's the list:

let list1 = ["#", "@", "#", "#"]

I need the output to look like this:

#@
##

I know that i could use the following to print every element on a new line:

mapM_ putStrLn list1 

but I'm not sure how to adapt this for only printing part of the list on a new line.

like image 236
mrg1023 Avatar asked Dec 29 '25 09:12

mrg1023


1 Answers

You want something like Data.Text.chunksOf for arbitrary lists, which I've never seen anywhere so I always reimplement it.

import Data.List (unfoldr)

-- This version ensures that the output consists of lists 
-- of equal length. To do so, it trims the input.
chunksOf :: Int -> [a] -> [[a]]
chunksOf n = unfoldr (test . splitAt n) where
  test (_, []) = Nothing
  test x       = Just x

Then we can take your [String] and turn it into [[String]], a list of lists each corresponding to String components of a line. We map concat over that list to merge up each line from its components, then use unlines to glue them all together.

grid :: Int -> [String] -> String
grid n = unlines . map concat . chunksOf n

Then we can print that string if desired

main :: IO ()
main = putStrLn $ grid 2 list1

Edit: apparently there is a chunksOf in a fairly popular library Data.List.Split. Their version is to my knowledge identical to mine, though it's implemented a little differently. Both of ours ought to satisfy

chunksOf n xs ++ chunksOf n ys == chunksOf n (xs ++ ys)

whenever length xs `mod` n == 0.

like image 114
J. Abrahamson Avatar answered Dec 30 '25 23:12

J. Abrahamson