2014-02-13 78 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