我正在尝试在Haskell中编写一个数独生成器/求解器作为学习练习,但是我在ST
monad中生成一个可变数组时遇到了困难。
我的parse
函数的输入将是String
个81个字符,其中包含数字1
到9
和占位符(.
,{{1 }},或-
)。
这是我写的函数,但它不会编译,我无法弄清楚我需要什么类型:
0
函数的输出应该是包含单元格的可变9 x 9网格的不可变表示。
我该如何解决这个问题?
答案 0 :(得分:1)
您正在使用runSTUArray
,这意味着有UArray (Int, Int) Cell
的意图。您无法做到这一点:UArray
仅适用于少数几种元素类型。您可以使用普通Array
。或者,您可以type Cell = Word16
并将Bool
填入其中。无论如何,没有理由使用ST
。 listArray
函数将执行:
import Data.Array
-- listArray :: Ix i => (i, i) -> [e] -> Array i e
parse :: String -> Array (Int, Int) Cell
parse = listArray ((0, 0), (8, 8)) . map chr2cell
where chr2cell c | isDigit c && c /= '0' = Cell (bit $ intToDigit c) True
| otherwise = Cell (2^11 - 2) False
如果您选择使用UArray _ Word16
,则只需稍微修改chr2cell
即可。如果你是最近的GHC,你甚至可以选择:
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
type Cell = Word16
pattern Cell :: Word16 -> Bool -> Word16
pattern Cell { values, original } <- (_ -> (values, original))
where Cell values original = _
您可以在其中填充第一个和第二个_
的函数,这些函数分别从Word16
和Bool
解构和构造单元格,以创建记录模式同义词像普通记录构造函数一样工作,但实际上并没有创建新类型。