В Haskell можно писать функции над индексированным по размеру списком, которые гарантируют, что мы никогда не выйдем за границы. Возможная реализация:
data Nat = Zero | Succ Nat deriving (Eq, Ord, Show)
infixr 5 :-
data Vec (n :: Nat) a where
Nil :: Vec 'Zero a
(:-) :: a -> Vec n a -> Vec ('Succ n) a
data Fin (n :: Nat) where
FZ :: Fin ('Succ n)
FS :: Fin n -> Fin ('Succ n)
vLookup :: Vec n a -> Fin n -> a
vLookup Nil _ = undefined
vLookup (x :- _) FZ = x
vLookup (_ :- xs) (FS i) = vLookup xs i
Конечно, это нормально для индексированных списков неизменяемого размера (также известных как Vec
).
Но как насчет изменчивых? Можно ли определить (или есть ли библиотека) индексированные массивы изменяемого размера в Haskell? Если такой библиотеки нет, то как ее реализовать?
Изменить 1: я искал Hackage и не нашел ни одной библиотеки, соответствующей моему описанию (размер индексированные изменяемые массивы).
Редактировать 2: я хотел бы упомянуть, что я думал использовать IORef
, чтобы получить желаемую изменчивость:
type Array n a = IORef (Vec n a)
но мне интересно, есть ли лучший (более эффективный, более элегантный) вариант...