2014-02-13 76 views
2

在阅读“学习你一个Haskell”的几章后,我想写一些东西并决定实现一个Sudoku求解器。我试图实现从这里B1功能:http://www.cse.chalmers.se/edu/year/2013/course/TDA555/lab3.html将[[Maybe Int]]转换为IO()

我的代码:

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 

我试图把它打印为

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

,但我只能把它打印为

[[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]] 

我很抱歉,如果这是对这样的初学者问题的错误地方。这只是我一直在尝试一段时间,并陷入一些相对微不足道的事情,而且越来越令人沮丧。谢谢

+1

'putStrLn $ unlines $ map(map(head.show))s'并替换0 – josejuan

+0

我会用'mapM_(putStrLn.map(也许'。'Data.Char.intToDigit))''但那不是去工作4x4 sudokus ... – yatima2975

回答

8

你非常接近!

的关键点是这个匿名函数:

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

顺便说一句,这里有2个警告标志:使用isNothingfromJust

现在,由于此函数返回数字,所以只能显示数字。但是你需要字符。因此,刚刚改写这个是以本地功能,如:

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

===编辑:更多的一般性建议===

无论何时你发现自己写:

if isNothing x then a else f (fromJust x) 

你应该更换与当地政府的明确功能或

maybe a f x 

在你的情况,你会开始写的只是:

​​

从而降低到更漂亮

maybe 0 id 

,现在你刚刚将其更改为:

maybe '.' (head . show) 

什么的。

+0

哦,我没有做适当的进口 import Data.Maybe(isJust,fromJust,isNothing) 或者你的意思是说这是一个糟糕的事情,使用这些功能? – dtan

+1

@dtan虽然你在这里使用它们的方式是安全的,但模式匹配通常是首选。请注意,'没有'需要解构价值,但'来自正义'需要解构它。我向你展示另一种选择。 – Ingo

+0

谢谢!我终于搞定了,结合你的答案和josejuan的。 'putStrLn。不合格。地图(地图showcell)$ rows s',然后在showcell中进行模式匹配。 – dtan