Нарушение целостности Data.Set без GeneralizedNewtypeDeriving

Код ниже использует небезопасныйGeneralizedNewtypeDeriving расширение, чтобы сломатьData.Set вставляя различные элементы с разнымиOrd экземпляры:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Data.Set
import System.Random

class AlaInt i where
  fromIntSet :: Set Integer -> Set i
  toIntSet :: Set i -> Set Integer
instance AlaInt Integer where
  fromIntSet = id
  toIntSet = id
newtype I = I Integer deriving (Eq, Show, AlaInt)
instance Ord I where compare (I n1) (I n2) = compare n2 n1 -- sic!  

insert' :: Integer -> Set Integer -> Set Integer
insert' n s = toIntSet $ insert (I n) $ fromIntSet s

randomInput = take 5000 $ zip (randomRs (0,9) gen) (randoms gen) where
    gen = mkStdGen 911

createSet = Prelude.foldr f empty where
    f (e,True) = insert e
    f (e,False) = insert' e

main = print $ toAscList $ createSet randomInput

Код печатает[1,3,5,7,8,6,9,6,4,2,0,9], Обратите внимание, что список неупорядочен и имеет9 дважды.

Можно ли выполнить эту атаку с использованием словаря, используя другие расширения, например,ConstraintKinds? Если да, можетData.Set быть переработан, чтобы быть устойчивым к таким атакам?

Ответы на вопрос(1)

Ваш ответ на вопрос