{-# LANGUAGE GeneralizedNewtypeDeriving #-}moduleGeneral.Intern(Intern ,Id (..),empty ,insert ,add ,lookup ,toList ,fromList )whereimportDevelopment.Shake.Classes importForeign.StorableimportData.WordimportPreludehiding(lookup)importqualifiedData.HashMap.StrictasMapimportData.List(foldl')-- Invariant: The first field is the highest value in the MapdataIntern a =Intern {-# UNPACK#-}!Word32!(Map.HashMapa Id )newtypeId =Id Word32deriving(Eq,Hashable,Ord,Binary,Show,NFData,Storable)empty::Intern a empty =Intern 0Map.emptyinsert::(Eqa ,Hashablea )=>a ->Id ->Intern a ->Intern a insert k v @(Id i )(Intern n mp )=Intern (maxn i )$Map.insertk v mp add::(Eqa ,Hashablea )=>a ->Intern a ->(Intern a ,Id )add k (Intern v mp )=(Intern v2 $Map.insertk (Id v2 )mp ,Id v2 )wherev2 =v +1lookup::(Eqa ,Hashablea )=>a ->Intern a ->MaybeId lookup k (Intern _mp )=Map.lookupk mp toList::Intern a ->[(a ,Id )]toList (Intern _mp )=Map.toListmp fromList::(Eqa ,Hashablea )=>[(a ,Id )]->Intern a fromList xs =Intern (foldl'max0[i |(_,Id i )<-xs ])(Map.fromListxs )