I currently have a 2D array declared as:
import Data.Array.Unboxed
listArray ((0,0), (9,9)) (replicate 100 'f') ∷ UArray (Int, Int) Char
I am trying to set a value in this array from a set of coordinates, (x, y)
stored as a tuple, changing the value into a t
, instead of an f
. I have fooled around with lenses, however, I have had no success with them.
Any help is appreciated!
To access individual elements of an array with lens
, you need to use the ix
method of the Ixed
class, defined in Control.Lens.At
. If you define
fooArray :: UArray (Int, Int) Char
fooArray = listArray ((0,0), (9,9)) (replicate 100 'f')
then, firing up GHCi,
> fooArray ^? ix (1,2)
Just 'f'
> let fooArray' = fooArray & ix (1,2) .~ 't'
> fooArray' ^? ix (1,2)
Just 't'
Note that editing arrays like this is pretty inefficient if the arrays are large; if you need high speed or lots of array edits, you may want to consider a different structure.
The easiest ways to smash an array flat are the elems
function from Data.Array.Unboxed
or toList
from Data.Foldable
. If what those give you is sideways, you can probably patch it up with ixmap
.
The simplest update function for arrays is (//)
, which has this type:
(//) :: (IArray a e, Ix i) => a i e -> [(i, e)] -> a i e
For example:
Data.Array.Unboxed> listArray (0, 4) "abcde" // [(1, 'f')] :: UArray Int Char
array (0,4) [(0,'a'),(1,'f'),(2,'c'),(3,'d'),(4,'e')]
You can access particular elements with (!)
:
Data.Array.Unboxed> it ! 1
'f'
来源:https://stackoverflow.com/questions/33093283/how-to-make-setters-in-2d-array-haskell