haskell - 如何从Haskell矩阵中的某个位置提取值?

标签 haskell matrix

我必须为 2048 实现一个游戏板。 我声明了:

type Board = [[Int]]

为了在随机单元格中添加新的随机值,我必须检查该单元格中的值,但我不知道如何获取该值。我见过使用 monad 的不同示例,但我不知道如何使用 Monad 并且我想知道是否还有其他方法可以做到这一点。

谁能帮我举个例子吗?

谢谢!

最佳答案

嗯,至于检查特定单元格中的值 - 这只是列表索引,您可以简单地使用 !!。由于列表是嵌套的,因此您需要两次查找,首先是行,然后是列/单元格。

type CellId = (Int,Int)

cellAt :: Board -> CellId -> Int
cellAt rows (idy, idx) = rows !! idy !! idx

我不太明显的是更新。要以函数式风格做到这一点,您需要一个类似的函数

updataCellAt :: CellId -> Int -> Board -> Board

它接受一个板作为参数,并返回一个修改后的板。

修改列表仅在一个位置很容易:头部。

replaceHead :: a -> [a] -> [a]
replaceHead _ [] = []
replaceHead x (_:xs) = x:xs

要修改任意位置,最好的办法是首先将该位置之前的所有内容拆分为列表,然后所有内容都在那里形成(因此第二个列表将该位置作为其头部)。

replaceAt :: Int -> a -> [a] -> [a]
replaceAt i x xs = let (prev, remain) = splitAt i xs
                   in prev ++ replaceHead x remain

现在,这不是很灵活:您只需丢弃替换的元素,但通常您可能只想对其应用转换

modifyHead :: (a->a) -> [a] -> [a]
modifyHead _ [] = []
modifyHead mdf (x:xs) = mdf x : xs

modifyAt :: Int -> (a->a) -> [a] -> [a]
modifyAt i mdf xs = let (prev, remain) = splitAt i xs
                    in prev ++ modifyHead mdf remain

现在可以轻松地使用此列表来修改嵌套列表,例如您的面板:

modifyCellAt :: CellId -> (a->a) -> [[a]] -> [[a]]
modifyCellAt (iy, ix) mdf = modifyAt iy (\row -> modifyAt ix mdf row)
               -- or short: modifyAt iy $ modifyAt ix mdf

关于haskell - 如何从Haskell矩阵中的某个位置提取值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23427728/

相关文章:

error-handling - EitherT 是如何工作的?

haskell - 有没有更好的方法来编写indexof函数?

java - java中如何将矩阵转换为图像

css - 组合 CSS 矩阵

excel - VBA:完成矩阵

java - 读取带有数字的txt文件并将其保存在字符串矩阵中

haskell - 这个函数是否利用了haskell的惰性求值

Haskell:通过 "Principled Transformations"简化函数

haskell - 如何编写一个以可变参数函数作为参数的 Haskell 函数

python - 维基百科页面上的塞德尔算法是否不正确?