В пакете crypto-api есть API Crypto.Random, который определяет, что значит для кого-то быть «генератором псевдослучайных чисел».
Я реализовал этот API с использованием экземпляра класса RandomGen System.Random, а именно StdGen:
instance CryptoRandomGen StdGen where
newGen bs = Right $ mkStdGen $ shift e1 24 + shift e2 16 + shift e3 8 + e4
where (e1 : e2 : e3 : e4 : _) = Prelude.map fromIntegral $ unpack bs
genSeedLength = Tagged 4
genBytes n g = Right $ genBytesHelper n empty g
where genBytesHelper 0 partial gen = (partial, gen)
genBytesHelper n partial gen = genBytesHelper (n-1) (partial `snoc` nextitem) newgen
where (nextitem, newgen) = randomR (0, 255) gen
reseed bs _ = newGen bs
Однако, эта реализация предназначена только для типа StdGen, но она действительно будет работать для всего в классе типов System.Random RandomGen.
Есть ли способ сказать, что все в RandomGen является членом CryptoRandomGen, используя данные функции подкладки? Я хотел бы иметь возможность сделать это в своем собственном коде, не меняя источник ни одной из этих двух библиотек. Мой инстинкт был бы изменить первую строку на что-то вроде
instance (RandomGen a) => CryptoRandomGen a where
но это не кажется синтаксически правильным.