数据网格的Haskell可变数组

时间:2018-03-17 21:53:46

标签: haskell monads mutable

我正在尝试在Haskell中编写一个数独生成器/求解器作为学习练习,但是我在ST monad中生成一个可变数组时遇到了困难。

我的parse函数的输入将是String个81个字符,其中包含数字19和占位符(.,{{1 }},或-)。

这是我写的函数,但它不会编译,我无法弄清楚我需要什么类型:

0

函数的输出应该是包含单元格的可变9 x 9网格的不可变表示。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您正在使用runSTUArray,这意味着有UArray (Int, Int) Cell的意图。您无法做到这一点:UArray仅适用于少数几种元素类型。您可以使用普通Array。或者,您可以type Cell = Word16并将Bool填入其中。无论如何,没有理由使用STlistArray函数将执行:

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 = _

您可以在其中填充第一个和第二个_的函数,这些函数分别从Word16Bool解构和构造单元格,以创建记录模式同义词像普通记录构造函数一样工作,但实际上并没有创建新类型。