Haskell做关键字

时间:2012-11-26 03:19:36

标签: haskell

所以我一直在努力解决过去几个小时打印数独游戏板的问题,我差不多完成了但是我已经陷入了最后一步。所以我所拥有的是一个数据板,表示为“列表列表”(即板= [[1,3,5,7,0,2,0,0,0],[3,4,5,... 。],...]

我已经能够使用以下功能打印出带格式的行:

line i s_board = intercalate " | " . map unwords . chunksOf 3 $ map show a
             where 
               a = s_board!!i 

所以通过像“0行”一样打电话,我会得到“1 3 5 | 7 0 2 | 0 0 0”,这是我需要的部分内容。接下来我尝试使用“do block”来输出我需要的板,看起来像这样:

print = do line 0 board 
        line 1 board 
        ...

这甚至不会编译,当我做这样的事情时:

print = do 
        line 0 board 
        line 1 board

多次打印适当的列表,这是相当混乱的。我想继续努力,包括额外的格式化,比如在每三行之后打印一个字符串,例如“----------”,以完成电路板,但我甚至无法让其他东西工作对了。我很感激对这些问题的任何帮助。

2 个答案:

答案 0 :(得分:7)

制作一个能让你的功能变得更容易,更优雅 板,制作一个大字符串,最后打印出来,而不是担心 通过do块打印每一行。

所以,如果我们简化你的线显示函数来占用一块板:

showLine :: [Int] -> String
showLine = intercalate " | "
         . map unwords
         . chunksOf 3
         . map show

然后,我们需要获取每一行的字符串表示并将它们全部放入 一起。这看起来非常像showLine代码:

showBoard :: [[Int]] -> String
showBoard = intercalate "---------------------\n"
          . map unlines
          . chunksOf 3
          . map showLine

使用示例板

-- Obviously not a valid sudoku board...
example :: [[Int]]
example = replicate 9 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

*Main> putStrLn $ showBoard example
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
---------------------
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
---------------------
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9

答案 1 :(得分:3)

您的原始尝试未编译,因为它违反了Haskell的布局规则。

第二个没有按照你的期望做,因为line n board是一个列表,所以do - 符号表示不确定,而不是IO动作的排序。如果您尝试输入类似

的类型
print :: IO ()

在你的函数之上(顺便提一下,print在标准前奏中定义,你应该收到关于遮蔽它的警告),类型检查器会告诉你你的错误。如果你真的想打印出这样的电路板(虽然正如另一个答案所示,构建一个字符串然后将整个事情打印出来要好得多),你可以试试

printBoard :: IO ()
printBoard = do print $ line 0 board
                print $ line 1 board

或打印整个板,

printBoard = mapM_ (print . showLine) board

其中showLineprint类似,但索引已被删除。