如何从Haskell矩阵中的某个位置提取值? [英] How to extract the value from a certain position in a matrix in Haskell?

查看:45
本文介绍了如何从Haskell矩阵中的某个位置提取值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须为 2048 实现游戏板.我宣布:

I have to implement a gameboard for 2048. I declared it:

type Board = [[Int]]

为了在随机单元格中添加新的随机值,我必须检查该单元格中的值,但是我不知道如何获取该值.我已经看到了使用monad的不同示例,但是我不知道如何使用 Monad ,并且我想知道是否还有另一种方法可以执行此操作.

In order to add a new random value in a random cell I must check the value in that cell, but I don't know how to get the value. I've seen different examples using a monad, but I don't know how to use Monad and I was wondering if there is another way to do this.

有人可以帮我举个例子吗?

Can anyone help me with an example?

谢谢!

推荐答案

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

Well, as for checking the value in a particular cell – that's just list-indexing, you can simply use !!. Since the list is nested you need two lookups, first the row then the column/cell.

type CellId = (Int,Int)

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

我不太清楚正在更新.要以功能性样式进行操作,您需要一个类似

I bit less obvious is updating. To do that in a functional style you need a function like

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

以木板作为参数,并返回修改后的木板.

that takes a board as an argument, and returns a modified board.

修改列表仅在一个地方很容易:头部.

Modifying a list is easy only at one spot: the head.

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

要修改任意位置,最好的方法是先将列表拆分成该位置之前的所有内容,然后在该位置上形成所有内容(因此第二个列表以该位置为首).

To modify an arbitrary spot, the best thing is to first split up the list in everything before that spot, and everything form there on (so the second list has the spot as its head).

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

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

Now, this is not very flexible: you're simply throwing away the replaced element, but in general you might want to only apply a transformation to it.

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

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

This one can now easily be used to modify a nested list, like your board:

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矩阵中的某个位置提取值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆