提问人:Ralph 提问时间:3/18/2018 更新时间:3/18/2018 访问量:136
数独网格的 Haskell 可变数组
Haskell mutable array for sudoku grid
问:
我正在尝试在 Haskell 中编写一个数独生成器/求解器作为学习练习,但我在 monad 中生成可变数组时遇到了困难。ST
我的函数的输入将是 81 个字符,其中包含数字 through 和占位符 (, , 或 )。parse
String
1
9
.
-
0
这是我写的函数,但它不会编译,我无法弄清楚我需要什么类型:
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赞
HTNW
3/18/2018
#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
如果您选择使用 ,您只需要稍作修改即可。如果您最近参加 GHC,您甚至可以选择:UArray _ Word16
chr2cell
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
type Cell = Word16
pattern Cell :: Word16 -> Bool -> Word16
pattern Cell { values, original } <- (_ -> (values, original))
where Cell values original = _
您可以在其中使用分别解构和构造 A 和 A 的单元格的函数填充第一个和第二个 S,以创建一个记录模式同义词,该同义词的工作方式与普通记录构造函数类似,但实际上不会创建新类型。_
Word16
Bool
评论
0赞
Ralph
3/18/2018
谢谢。这是非常有帮助的。
评论