我'm trying to write a sudoku generator/solver in Haskell as a learning exercise, but I'm在 ST
monad中遇到难以产生可变数组的问题 .
我的 parse
函数的输入将是 String
,包含数字 1
到 9
和占位符( .
, -
或 0
)的81个字符 .
这是我写的函数,但它不会编译,我无法弄清楚我需要什么类型:
import Control.Monad
import Control.Monad.ST
import Data.Array.ST
import qualified Data.Array.Unboxed as U
import Data.Char (digitToInt, isDigit)
import Data.List (zip)
data Cell = Cell
{ values :: Word16
, original :: Bool
} deriving (Show)
parse input =
runSTUArray $
U.array ((0, 0), (8, 8)) $
map
(\(i, d) ->
( (quot i 9, mod i 9)
, if isDigit d && d /= '0'
then Cell {values = bit $ digitToInt d, original = True}
else Cell {values = 2 ^ 11 - 2, original = False})) $
zip [0 ..] input
函数的输出应该是包含单元格的可变9 x 9网格的不可变表示 .
我怎样才能解决这个问题?
1 回答
您正在使用
runSTUArray
,这意味着有UArray (Int, Int) Cell
的意图 . 你不能这样:UArray
仅适用于少数几种元素类型 . 你可以使用普通的Array
. 或者,您可以拥有type Cell = Word16
并将Bool
填入其中 . 无论如何,没有理由使用ST
.listArray
函数将执行:如果您选择使用
UArray _ Word16
,则只需稍微修改chr2cell
即可 . 如果你是最近的GHC,你甚至可以选择:您可以在其中填充第一个和第二个
_
,其功能分别为Word16
和Bool
解构和构造单元格,以创建一个记录模式同义词,它就像普通记录构造函数一样,但实际上并不创建新的类型 .