Storable
призвано вызвать идею C struct
s. Как struct
, любой тип Storable
имеет ограниченный размер. Storable (Symmetric n)
возможно, потому что Symmetric n
на самом деле ограниченного размера. (Предполагая, что Cyclic n
s эквивалентны по модулю n
,). Он имеет значения n!
, которые являются конечными, и поэтому вам не нужно неограниченное пространство. В частности, достаточно log2(n!)
битов. Обратите внимание, что я говорю о Symmetric n
для некоторого конкретного n
. Для разных Nat
с n
, m
и т. Д. Symmetric n
, Symmetric m
и т. Д. Имеют разные типы, и поэтому они могут иметь разные размеры. Для одного n :: Nat
, Symmetric n
имеет фиксированный размер.
Реальная проблема заключается в выборе кодировки. Для простоты реализации вы можете использовать рекурсивное кодирование, где Storable n
состоит из ceil(log2(n) / 8)
байтов для хранения первого числа, за которым следует Storable (n - 1)
. Тогда Symmetric 1
будет 0 байтов, Symmetric 2
будет 1 байтом (используется только один бит), Symmetric 3
будет 2 байта, ..., Symmetric 256
будет 255 байтов, Symmetric 257
будет 257 байтов (потому что первое число имеет 257 вариантов выбора и поэтому требует двух байтов). Это, конечно, неэффективно, но вы можете ясно видеть, что для каждого Symmetric n
есть четко определенный размер. Если вы хотите перейти к пределу log2(n!)
битов (на самом деле, ceil(log2(n!)/8)
байт), вам придется сделать некоторую ~~ фанк-математику ~~ (с которой я не знаком), но вы можете сделатьэто.
Вам нужны одиночные, чтобы сделать эту работу;можно написать
instance KnownNat n => Storable (Symmetric n)
, но не
instance Storable (Symmetric n)
Типы стираются, поэтому второй instance
не сообщается, что такое n
, и, следовательно, ничего не может прочитать (или внедрить sizeof
и т. д.). Он может писать, потому что Symmetric
является GADT и, таким образом, содержит информацию о том, что такое n
.
Примечание: не должно ли Symmetric 0
быть непустым?
data Symmetric (n :: Nat) where
S0 :: Symmetric 0
(:.) :: Cyclic n -> Symmetric (n - 1) -> Symmetric n
Symmetric 0
- это набор биекций из пустого набора в себя, и в нем есть только одна функция (пустой набор)комплект.