module Data.IOMatrix import Data.IOArray.Prims %default total export record IOMatrix a where constructor MkIOMatrix maxWidth : Int maxHeight : Int content : ArrayData (Maybe a) export width : IOMatrix a -> Int width = maxWidth export height : IOMatrix a -> Int height = maxHeight export new : HasIO io => (width, height : Int) -> io (IOMatrix a) new width height = pure $ MkIOMatrix width height !(primIO (prim__newArray (width * height) Nothing)) toPosition : IOMatrix a -> Int -> Int -> Maybe Int toPosition (MkIOMatrix w h arr) i j = do guard (not (i < 0 || j < 0 || i >= w || j >= h)) pure (i * h + j) export write : HasIO io => IOMatrix a -> Int -> Int -> a -> io Bool write mat i j el = case toPosition mat i j of Nothing => pure False Just pos => True <$ primIO (prim__arraySet (content mat) pos (Just el)) export read : HasIO io => IOMatrix a -> Int -> Int -> io (Maybe a) read mat i j = case toPosition mat i j of Nothing => pure Nothing Just pos => primIO (prim__arrayGet (content mat) pos)