How to extract the value from a certain position in a matrix in Haskell?

烈酒焚心 提交于 2021-02-10 05:40:30

问题


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

type Board = [[Int]]

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?

Thanks!


回答1:


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

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


来源:https://stackoverflow.com/questions/23427728/how-to-extract-the-value-from-a-certain-position-in-a-matrix-in-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!