@@ -36,10 +36,11 @@ import Data.Function (on)
36import Data.Kind (Type)
36import Data.Kind (Type)
37import Data.Type.Equality ((:~:) (..), TestEquality (..))
37import Data.Type.Equality ((:~:) (..), TestEquality (..))
38import Data.List (intercalate, nubBy)
38import Data.List (intercalate, nubBy)
39+import Data.Maybe (fromMaybe)
39import Data.Primitive.Array (Array, MutableArray, indexArray, mapArray', readArray, sizeofArray,
40import Data.Primitive.Array (Array, MutableArray, indexArray, mapArray', readArray, sizeofArray,
40 thawArray, unsafeFreezeArray, writeArray)
41 thawArray, unsafeFreezeArray, writeArray)
41import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
42import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
42−import Data.Semigroup (Semigroup (..))
43+import Data.Semigroup (Semigroup (..), All(..))
43import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
44import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
44import GHC.Exts (IsList (..), inline, sortWith)
45import GHC.Exts (IsList (..), inline, sortWith)
45import GHC.Fingerprint (Fingerprint (..))
46import GHC.Fingerprint (Fingerprint (..))
@@ -448,3 +449,62 @@ fromSortedList l = runST $ do
448 newFirst <- loop (2 * i + 1) first
449 newFirst <- loop (2 * i + 1) first
449 writeArray result i (indexArray origin newFirst)
450 writeArray result i (indexArray origin newFirst)
450 loop (2 * i + 2) (newFirst + 1)
451 loop (2 * i + 2) (newFirst + 1)
453+----------------------------------------------------------------------------
455+----------------------------------------------------------------------------
457+-- | Check that invariant of the structure is hold.
458+-- The structure maintains the following invariant.
459+-- For each element @A@ at index @i@:
461+-- 1. if there is an element @B@ at index @2*i+1@,
464+-- 2. if there is an element @C@ at index @2*i+2@,
467+invariantCheck :: TypeRepMap f -> Bool
468+invariantCheck TypeRepMap{..} = getAll (check 0)
470+ lastMay [] = Nothing
471+ lastMay [x] = Just x
472+ lastMay (_:xs) = lastMay xs
473+ sz = sizeofPrimArray fingerprintAs
474+ check i | i >= sz = All True
478+ -- maximum value in the left branch
480+ fmap (\j -> (indexPrimArray fingerprintAs j, indexPrimArray fingerprintBs j))
483+ $ iterate (\j -> j*2+2) left
484+ -- minimum value in the right branch
486+ fmap (\j -> (indexPrimArray fingerprintAs j, indexPrimArray fingerprintBs j))
489+ $ iterate (\j -> j*2+1) right
494+ case indexPrimArray fingerprintAs i `compare` indexPrimArray fingerprintAs left of
496+ EQ -> indexPrimArray fingerprintBs i >= indexPrimArray fingerprintBs left
502+ case indexPrimArray fingerprintAs i `compare` indexPrimArray fingerprintAs right of
504+ EQ -> indexPrimArray fingerprintBs i <= indexPrimArray fingerprintBs right
507+ , All $ fromMaybe True $ (<=) <$> leftMax <*> rightMin