dtan
dtan

Reputation: 69

Converting [[Maybe Int]] to IO ()

After going through a couple of chapters of "Learn You A Haskell", I wanted to write something hands on and decided to implement a Sudoku solver.I am trying to implement the B1 function from here: http://www.cse.chalmers.se/edu/year/2013/course/TDA555/lab3.html

My code:

data Sudoku = Sudoku { getSudoku :: [[Maybe Int]] } deriving (Show, Eq)

rows :: Sudoku -> [[Maybe Int]]
rows (Sudoku rs) = rs

example :: Sudoku
example = Sudoku
    [ [Just 3, Just 6, Nothing,Nothing,Just 7, Just 1, Just 2, Nothing,Nothing]
    , [Nothing,Just 5, Nothing,Nothing,Nothing,Nothing,Just 1, Just 8, Nothing]
    , [Nothing,Nothing,Just 9, Just 2, Nothing,Just 4, Just 7, Nothing,Nothing]
    , [Nothing,Nothing,Nothing,Nothing,Just 1, Just 3, Nothing,Just 2, Just 8]
    , [Just 4, Nothing,Nothing,Just 5, Nothing,Just 2, Nothing,Nothing,Just 9]
    , [Just 2, Just 7, Nothing,Just 4, Just 6, Nothing,Nothing,Nothing,Nothing]
    , [Nothing,Nothing,Just 5, Just 3, Nothing,Just 8, Just 9, Nothing,Nothing]
    , [Nothing,Just 8, Just 3, Nothing,Nothing,Nothing,Nothing,Just 6, Nothing]
    , [Nothing,Nothing,Just 7, Just 6, Just 9, Nothing,Nothing,Just 4, Just 3]
    ]

printSudoku :: Sudoku -> IO ()
printSudoku s = do
    print . map (map (\x -> if isNothing x then 0 else fromJust x)) $ rows s

I am trying to get it to print as

Sudoku> printSudoku example
36..712..
.5....18.
..92.47..
....13.28
4..5.2..9
27.46....
..53.89..
.83....6.
..769..43

but I can only get it to print as

[[3,6,0,0,7,1,2,0,0],[0,5,0,0,0,0,1,8,0],[0,0,9,2,0,4,7,0,0],[0,0,0,0,1,3,0,2,8],[4,0,0,5,0,2,0,0,9],[2,7,0,4,6,0,0,0,0],[0,0,5,3,0,8,9,0,0],[0,8,3,0,0,0,0,6,0],[0,0,7,6,9,0,0,4,3]]

I apologize if this is the wrong place for such beginner questions. It's just that I have been trying for a while and getting stuck on something relatively trivial and its getting frustrating. Thanks

Upvotes: 2

Views: 864

Answers (1)

Ingo
Ingo

Reputation: 36339

You are very near!

The key point is this anonymous function:

(\x -> if isNothing x then 0 else fromJust x)

BTW, there are 2 warning flags here: The use of isNothing and fromJust.

Now, as this function returns numbers, you can have only numbers displayed. But you want characters instead. Hence, just rewrite this as a local function like:

 showcell Nothing  = '.'
 showcell (Just n) = ....

=== EDIT: More general advice ===

Whenever you find yourself writing:

if isNothing x then a else f (fromJust x)

you should replace it with an explicit local function or

maybe a f x

In your case, you'd initially written just:

(\x -> maybe 0 id x)

which reduces to the much nicer

maybe 0 id

and now you just had to change it to:

maybe '.' (head . show)

or something.

Upvotes: 8

Related Questions