【发布时间】:2021-03-05 12:25:53
【问题描述】:
我正在尝试构建俄罗斯方块的命令行版本来练习我的 Haskell 技能。对于游戏板,我使用 UArray,因为我可以冻结和解冻它,这使我可以查看当前的俄罗斯方块是否与当前放置的块发生碰撞,而无需搜索整个板(如果我使用过的列表)。我遇到了一个问题,我不确定如何将此数组转换为Text 或String 以将其输出到控制台。
现在我只处理电路板的一排,我使用以下函数对其进行初始化:
gameBoardWidth = 10 :: Int
initBoard :: UArray Int Char
initBoard = runSTUArray $ do
let lastCol = gameBoardWidth - 1
row <- newArray (0,lastCol) ' '
return row
现在我不确定如何将Char 从阵列中取出以进行打印。 From the standard Array interface elems 看起来像我需要的,但这似乎不适用于 UArrays。
*Main Console Lib Paths_haskell_tetris Data.Array> elems initBoard
• Couldn't match expected type ‘Array i0 e’
with actual type ‘Data.Array.Base.UArray Int Char’
我的另一个想法是尝试在 do 块中使用 readArray 函数,但我不确定如何在函数语言中连接每个字符串的结果
如果我的问题与我导入的包有关,这些是我的导入:
import Data.Array.Unboxed
import Data.Array.ST
import Control.Monad
import Control.Monad.ST
【问题讨论】:
-
@WillemVanOnsem 感谢您的回复。那么问题是我通过使用
runSTUArray将数组从它的一元上下文中取出,并且我需要将它放回它的上下文中以便实际读取和写入它吗?IOUArray和STUArray有什么区别,它们看起来是同一个接口,只是它们内部实现不同? -
在您的测试中,您调用的是
Data.Array.elems,但看起来您需要调用Data.Array.IArray.elems。也许import qualified ... as ...可以帮助您指出“正确”的功能。顺便说一句,不断冻结/解冻您的阵列是有代价的,因为您需要制作副本。 Willem 建议的可变数组应该更高效,因为它大致相当于我们在命令式语言中得到的数组。 -
@chi 可以,如果在 GHCI 中运行
> Data.Array.IArray.elems initBoard,我会得到" ",这是我所期望的。出于某种原因,您的答案并没有以我可以接受的方式显示
标签: arrays haskell functional-programming io monads