Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell if else list comprehension

I'm trying to print out a board in the right way, like this:

  1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  
 1.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 2.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 3.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 4.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 5.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 6.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 7.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 8.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
 9.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
10.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
11.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
12.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
13.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
14.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
15.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
16.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
17.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         
18.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .         

I have the list comprehension here

 ((concat [(""++show i)++"   " | i <- [1..n], i<10])++"\n")

I can get the 9 first numbers correctly, but the problem comes when i would like to put an else statement in my comprehension. I can't seem to know how to do that. So to make my self extra clear, i would like to do the same thing with the double digits but the only difference will be that i want two spaces instead of three between each double digit.

like image 807
ruubel Avatar asked Oct 29 '22 23:10

ruubel


1 Answers

The left hand of the list comprehension accepts any Haskell expression, so we can write the if-then-else in the left hand of the list comprehension and omit the i < 10 condition on the right hand:

concat [(""++show i)++if i < 10 then "   " else "  " | i &lt- [1..n]]++"\n"

For n = 15, this then produces:

Prelude> concat [(""++show i)++if i < 10 then "   " else "  " | i <- [1..n]]++"\n"
"1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  \n"

We can also remove the ""++ part on the left side of the list comprehension, since this is bascially a no operation:

concat [show i ++ if i < 10 then "   " else "  " | i &lt- [1..n]] ++ "\n"

The above is however not very elegant: if i = 123, then we still will run into trouble. We can calculate the length of the show, calculate 4-l (with l the length), and add this as extra spacing. For instance:

concat [s ++ replicate (4-length s) ' ' | i &lt- [1..n], let s = show i] ++ "\n"

There are also some more dedicated formatting and joining functions, but since the exercise is probably to get familier with lists, I think this is out of scope here.

Like @4castle says, we can use for instance printf:

import Text.Printf(printf)

concatMap (printf "%-4d") [1..n] ++ "\n"
like image 160
Willem Van Onsem Avatar answered Nov 15 '22 09:11

Willem Van Onsem