难以在函数中获得所需的输出文件类型

时间:2014-02-13 11:05:40

标签: haskell

在经历了“了解你一个Haskell”的几章后,我想亲自动手并决定实现一个数独求解器。我正试图从这里实现B2函数:http://www.cse.chalmers.se/edu/year/2013/course/TDA555/lab3.html < / p>

这是我的代码:

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

printSudoku :: Sudoku -> IO ()
printSudoku s = do
putStrLn . unlines . map (map (maybe '.' (head . show))) $ rows s

stringToSudoku :: String -> [[Maybe Int]]
stringToSudoku [] = []
stringToSudoku s = (f x):stringToSudoku y
    where (x,y) = splitAt 9 s
        f = map (\x -> if (digitToInt x)==0 then Nothing else Just (digitToInt x))


readSudoku :: FilePath -> IO Sudoku
readSudoku path = do
    handle <- openFile path ReadMode
    contents <- hGetContents handle
    return $ Sudoku $ stringToSudoku contents

我能够获得所需的输出:

readSudoku "sudoku.txt" >>= printSudoku 
.......1.
4........
.2.......
....5.4.7
..8...3..
..1.9....
3..4..2..
.5.1.....
...8.6...

但是,我必须在readSudoku函数中将[[Maybe Int]]转换为Sudoku。应该可以在stringToSudoku函数中执行此操作吗?

sudoku.txt文件包含1行     000000010400000000020000000000050407008000300001090000300400200050100000000806000

1 个答案:

答案 0 :(得分:3)

如果您希望stringToSudoku返回Sudoku,您可以执行以下操作:

stringToSudoku :: String -> Sudoku
stringToSudoku s = Sudoku $ stringToGrid s
    where stringToGrid [] = []
          stringToGrid s = let (x, y) = splitAt 9 s
                               f = map (\x -> if (digitToInt x)==0 then Nothing else Just (digitToInt x))
                           in (f x):stringToGrid y