{-# language CPP #-} {-# language BangPatterns, ScopedTypeVariables, UnboxedTuples, MagicHash #-} {-# language DeriveTraversable, StandaloneDeriving #-} {-# language PatternSynonyms #-} {-# language ViewPatterns #-} {-# language FlexibleContexts #-} {- OPTIONS_GHC -Wall #-} {- OPTIONS_GHC -ddump-simpl #-} module Data.CompactSequence.Deque.Internal where import qualified Data.CompactSequence.Internal.Array as A import Data.CompactSequence.Internal.Array (Array) import qualified Data.CompactSequence.Internal.Size as Sz import Data.CompactSequence.Internal.Size (Size, Twice) import qualified Data.CompactSequence.Internal.Numbers as N import qualified Data.Foldable as F import Control.Monad.Trans.State.Strict import Data.Function (on) data Deque n a = Empty | Shallow !(Array n a) | Deep11 !(Array n a) !(Deque (Twice n) a) !(Array n a) | Deep12 !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) | Deep13 !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) | Deep14 !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) !(Array n a) | Deep21 !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) | Deep22 !(Array n a) !(Array n a) (Deque (Twice n) a) !(Array n a) !(Array n a) | Deep23 !(Array n a) !(Array n a) (Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) | Deep24 !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) !(Array n a) | Deep31 !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) | Deep32 !(Array n a) !(Array n a) !(Array n a) (Deque (Twice n) a) !(Array n a) !(Array n a) | Deep33 !(Array n a) !(Array n a) !(Array n a) (Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) | Deep34 !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) !(Array n a) | Deep41 !(Array n a) !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) | Deep42 !(Array n a) !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) | Deep43 !(Array n a) !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) | Deep44 !(Array n a) !(Array n a) !(Array n a) !(Array n a) !(Deque (Twice n) a) !(Array n a) !(Array n a) !(Array n a) !(Array n a) deriving (Functor, Foldable, Traversable) instance Eq a => Eq (Deque n a) where (==) = (==) `on` F.toList instance Ord a => Ord (Deque n a) where compare = compare `on` F.toList empty :: Deque n a empty = Empty consA :: Size n -> Array n a -> Deque n a -> Deque n a consA !_ !sa Empty = Shallow sa consA !_ !sa1 (Shallow sa2) = Deep11 sa1 Empty sa2 consA !_ !x (Deep11 sa m ta) = Deep21 x sa m ta consA !_ !x (Deep12 sa m ta1 ta2) = Deep22 x sa m ta1 ta2 consA !_ !x (Deep13 sa m ta1 ta2 ta3) = Deep23 x sa m ta1 ta2 ta3 consA !_ !x (Deep14 sa m ta1 ta2 ta3 ta4) = Deep24 x sa m ta1 ta2 ta3 ta4 consA !_ !x (Deep21 sa1 sa2 m ta) = Deep31 x sa1 sa2 m ta consA !_ !x (Deep22 sa1 sa2 m ta1 ta2) = Deep32 x sa1 sa2 m ta1 ta2 consA !_ !x (Deep23 sa1 sa2 m ta1 ta2 ta3) = Deep33 x sa1 sa2 m ta1 ta2 ta3 consA !_ !x (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) = Deep34 x sa1 sa2 m ta1 ta2 ta3 ta4 consA !_ !x (Deep31 sa1 sa2 sa3 m ta) = Deep41 x sa1 sa2 sa3 m ta consA !_ !x (Deep32 sa1 sa2 sa3 m ta1 ta2) = Deep42 x sa1 sa2 sa3 m ta1 ta2 consA !_ !x (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) = Deep43 x sa1 sa2 sa3 m ta1 ta2 ta3 consA !_ !x (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) = Deep44 x sa1 sa2 sa3 m ta1 ta2 ta3 ta4 consA !n !x (Deep41 sa1 sa2 sa3 sa4 m ta) | ShiftedR m' me1 me2 <- shiftRA n sa3 sa4 m = Deep33 x sa1 sa2 m' me1 me2 ta consA !n !x (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) = Deep32 x sa1 sa2 (consA (Sz.twice n) (A.append n sa3 sa4) m) ta1 ta2 consA !n !x (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) = Deep33 x sa1 sa2 (consA (Sz.twice n) (A.append n sa3 sa4) m) ta1 ta2 ta3 consA !n !x (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) = Deep32 x sa1 sa2 (consSnocA (Sz.twice n) (A.append n sa3 sa4) m (A.append n ta1 ta2)) ta3 ta4 snocA :: Size n -> Deque n a -> Array n a -> Deque n a snocA !_ Empty x = Shallow x snocA !_ (Shallow sa) x = Deep11 sa Empty x snocA !_ (Deep11 sa m ta) x = Deep12 sa m ta x snocA !_ (Deep21 sa1 sa2 m ta) x = Deep22 sa1 sa2 m ta x snocA !_ (Deep31 sa1 sa2 sa3 m ta) x = Deep32 sa1 sa2 sa3 m ta x snocA !_ (Deep41 sa1 sa2 sa3 sa4 m ta) x = Deep42 sa1 sa2 sa3 sa4 m ta x snocA !_ (Deep12 sa m ta1 ta2) x = Deep13 sa m ta1 ta2 x snocA !_ (Deep22 sa1 sa2 m ta1 ta2) x = Deep23 sa1 sa2 m ta1 ta2 x snocA !_ (Deep32 sa1 sa2 sa3 m ta1 ta2) x = Deep33 sa1 sa2 sa3 m ta1 ta2 x snocA !_ (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) x = Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 x snocA !_ (Deep13 sa m ta1 ta2 ta3) x = Deep14 sa m ta1 ta2 ta3 x snocA !_ (Deep23 sa1 sa2 m ta1 ta2 ta3) x = Deep24 sa1 sa2 m ta1 ta2 ta3 x snocA !_ (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) x = Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 x snocA !_ (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) x = Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 x snocA !n (Deep14 sa1 m ta1 ta2 ta3 ta4) x | ShiftedL mb1 mb2 m' <- shiftLA n m ta1 ta2 = Deep33 sa1 mb1 mb2 m' ta3 ta4 x snocA !n (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) x = Deep23 sa1 sa2 (snocA (Sz.twice n) m (A.append n ta1 ta2)) ta3 ta4 x snocA !n (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) x = Deep33 sa1 sa2 sa3 (snocA (Sz.twice n) m (A.append n ta1 ta2)) ta3 ta4 x snocA !n (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) x = Deep23 sa1 sa2 (consSnocA (Sz.twice n) (A.append n sa3 sa4) m (A.append n ta1 ta2)) ta3 ta4 x data ViewL n a = EmptyL | ConsL !(Array n a) (Deque n a) data ViewR n a = EmptyR | SnocR (Deque n a) !(Array n a) viewLA :: Size n -> Deque n a -> ViewL n a viewLA !_ Empty = EmptyL viewLA !_ (Shallow sa) = ConsL sa Empty viewLA !_ (Deep41 sa1 sa2 sa3 sa4 m ta1) = ConsL sa1 (Deep31 sa2 sa3 sa4 m ta1) viewLA !_ (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) = ConsL sa1 (Deep32 sa2 sa3 sa4 m ta1 ta2) viewLA !_ (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) = ConsL sa1 (Deep33 sa2 sa3 sa4 m ta1 ta2 ta3) viewLA !_ (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) = ConsL sa1 (Deep34 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) viewLA !_ (Deep31 sa1 sa2 sa3 m ta1) = ConsL sa1 (Deep21 sa2 sa3 m ta1) viewLA !_ (Deep32 sa1 sa2 sa3 m ta1 ta2) = ConsL sa1 (Deep22 sa2 sa3 m ta1 ta2) viewLA !_ (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) = ConsL sa1 (Deep23 sa2 sa3 m ta1 ta2 ta3) viewLA !_ (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) = ConsL sa1 (Deep24 sa2 sa3 m ta1 ta2 ta3 ta4) viewLA !_ (Deep21 sa1 sa2 m ta1) = ConsL sa1 (Deep11 sa2 m ta1) viewLA !_ (Deep22 sa1 sa2 m ta1 ta2) = ConsL sa1 (Deep12 sa2 m ta1 ta2) viewLA !_ (Deep23 sa1 sa2 m ta1 ta2 ta3) = ConsL sa1 (Deep13 sa2 m ta1 ta2 ta3) viewLA !_ (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) = ConsL sa1 (Deep14 sa2 m ta1 ta2 ta3 ta4) viewLA !n (Deep11 sa1 m ta1) = ConsL sa1 $ case unconsUnsnocA (Sz.twice n) m of EmptyUCUS -> Shallow ta1 OneUCUS mb | (mb1, mb2) <- A.splitArray n mb -> Deep21 mb1 mb2 Empty ta1 UCUS mb m' me | (mb1, mb2) <- A.splitArray n mb , (me1, me2) <- A.splitArray n me -> Deep23 mb1 mb2 m' me1 me2 ta1 viewLA !n (Deep12 sa1 m ta1 ta2) = ConsL sa1 $ case viewLA (Sz.twice n) m of EmptyL -> Deep11 ta1 Empty ta2 ConsL mb m' | (mb1, mb2) <- A.splitArray n mb -> Deep22 mb1 mb2 m' ta1 ta2 viewLA !n (Deep13 sa1 m ta1 ta2 ta3) = ConsL sa1 $ case viewLA (Sz.twice n) m of EmptyL -> Deep21 ta1 ta2 Empty ta3 ConsL mb m' | (mb1, mb2) <- A.splitArray n mb -> Deep23 mb1 mb2 m' ta1 ta2 ta3 viewLA !n (Deep14 sa1 m ta1 ta2 ta3 ta4) = ConsL sa1 $ case shiftLA n m ta1 ta2 of ShiftedL mb1 mb2 m' -> Deep22 mb1 mb2 m' ta3 ta4 viewRA :: Size n -> Deque n a -> ViewR n a viewRA !_ Empty = EmptyR viewRA !_ (Shallow sa) = SnocR Empty sa viewRA !_ (Deep14 sa1 m ta1 ta2 ta3 ta4) = SnocR (Deep13 sa1 m ta1 ta2 ta3) ta4 viewRA !_ (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) = SnocR (Deep23 sa1 sa2 m ta1 ta2 ta3) ta4 viewRA !_ (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) = SnocR (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) ta4 viewRA !_ (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) = SnocR (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) ta4 viewRA !_ (Deep13 sa1 m ta1 ta2 ta3) = SnocR (Deep12 sa1 m ta1 ta2) ta3 viewRA !_ (Deep23 sa1 sa2 m ta1 ta2 ta3) = SnocR (Deep22 sa1 sa2 m ta1 ta2) ta3 viewRA !_ (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) = SnocR (Deep32 sa1 sa2 sa3 m ta1 ta2) ta3 viewRA !_ (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) = SnocR (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) ta3 viewRA !_ (Deep12 sa1 m ta1 ta2) = SnocR (Deep11 sa1 m ta1) ta2 viewRA !_ (Deep22 sa1 sa2 m ta1 ta2) = SnocR (Deep21 sa1 sa2 m ta1) ta2 viewRA !_ (Deep32 sa1 sa2 sa3 m ta1 ta2) = SnocR (Deep31 sa1 sa2 sa3 m ta1) ta2 viewRA !_ (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) = SnocR (Deep41 sa1 sa2 sa3 sa4 m ta1) ta2 viewRA !n (Deep11 sa1 m ta1) = flip SnocR ta1 $ case unconsUnsnocA (Sz.twice n) m of EmptyUCUS -> Shallow sa1 OneUCUS mb | (m1, m2) <- A.splitArray n mb -> Deep21 sa1 m1 Empty m2 UCUS mb m' me | (mb1, mb2) <- A.splitArray n mb , (me1, me2) <- A.splitArray n me -> Deep32 sa1 mb1 mb2 m' me1 me2 viewRA !n (Deep21 sa1 sa2 m ta1) = flip SnocR ta1 $ case viewRA (Sz.twice n) m of EmptyR -> Deep11 sa1 Empty sa2 SnocR m' me | (me1, me2) <- A.splitArray n me -> Deep22 sa1 sa2 m' me1 me2 viewRA !n (Deep31 sa1 sa2 sa3 m ta1) = flip SnocR ta1 $ case viewRA (Sz.twice n) m of EmptyR -> Deep21 sa1 sa2 Empty sa3 SnocR m' me | (me1, me2) <- A.splitArray n me -> Deep32 sa1 sa2 sa3 m' me1 me2 viewRA !n (Deep41 sa1 sa2 sa3 sa4 m ta1) = flip SnocR ta1 $ case shiftRA n sa3 sa4 m of ShiftedR m' me1 me2 -> Deep22 sa1 sa2 m' me1 me2 data ShiftedL n a = ShiftedL !(Array n a) !(Array n a) (Deque (Twice n) a) data ShiftedR n a = ShiftedR (Deque (Twice n) a) !(Array n a) !(Array n a) shiftLA :: Size n -> Deque (Twice n) a -> Array n a -> Array n a -> ShiftedL n a shiftLA !_ Empty !sa1 !sa2 = ShiftedL sa1 sa2 Empty shiftLA !n (Shallow sa) !ta1 !ta2 = shriftL n sa (Shallow (A.append n ta1 ta2)) shiftLA !n (Deep11 sa1 m ta1) !x !y = shriftL n sa1 $ case viewLA (Sz.twice (Sz.twice n)) m of EmptyL -> Deep11 ta1 Empty (A.append n x y) ConsL mb m' | (mb1, mb2) <- A.splitArray (Sz.twice n) mb -> Deep22 mb1 mb2 m' ta1 (A.append n x y) shiftLA !n (Deep12 sa1 m ta1 ta2) !x !y = shriftL n sa1 $ case viewLA (Sz.twice (Sz.twice n)) m of EmptyL -> Deep21 ta1 ta2 Empty (A.append n x y) ConsL mb m' | (mb1, mb2) <- A.splitArray (Sz.twice n) mb -> Deep23 mb1 mb2 m' ta1 ta2 (A.append n x y) shiftLA !n (Deep13 sa1 m ta1 ta2 ta3) !x !y = shriftL n sa1 $ case shiftLA (Sz.twice n) m ta1 ta2 of ShiftedL mb1 mb2 m' -> Deep22 mb1 mb2 m' ta3 (A.append n x y) shiftLA !n (Deep14 sa1 m ta1 ta2 ta3 ta4) !x !y = shriftL n sa1 $ case shiftLA (Sz.twice n) m ta1 ta2 of ShiftedL mb1 mb2 m' -> Deep23 mb1 mb2 m' ta3 ta4 (A.append n x y) shiftLA !n (Deep21 sa1 sa2 m ta1) !x !y = shriftL n sa1 $ Deep12 sa2 m ta1 (A.append n x y) shiftLA !n (Deep22 sa1 sa2 m ta1 ta2) !x !y = shriftL n sa1 $ Deep13 sa2 m ta1 ta2 (A.append n x y) shiftLA !n (Deep23 sa1 sa2 m ta1 ta2 ta3) !x !y = shriftL n sa1 $ Deep14 sa2 m ta1 ta2 ta3 (A.append n x y) shiftLA !n (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) !x !y = shriftL n sa1 $ case shiftLA (Sz.twice n) m ta1 ta2 of ShiftedL mb1 mb2 m' -> Deep33 sa2 mb1 mb2 m' ta3 ta4 (A.append n x y) shiftLA !n (Deep31 sa1 sa2 sa3 m ta1) !x !y = shriftL n sa1 $ Deep22 sa2 sa3 m ta1 (A.append n x y) shiftLA !n (Deep32 sa1 sa2 sa3 m ta1 ta2) !x !y = shriftL n sa1 $ Deep23 sa2 sa3 m ta1 ta2 (A.append n x y) shiftLA !n (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) !x !y = shriftL n sa1 $ Deep24 sa2 sa3 m ta1 ta2 ta3 (A.append n x y) shiftLA !n (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) !x !y = shriftL n sa1 $ Deep23 sa2 sa3 (snocA (Sz.twice (Sz.twice n)) m (A.append (Sz.twice n) ta1 ta2)) ta3 ta4 (A.append n x y) shiftLA !n (Deep41 sa1 sa2 sa3 sa4 m ta1) !x !y = shriftL n sa1 $ Deep32 sa2 sa3 sa4 m ta1 (A.append n x y) shiftLA !n (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) !x !y = shriftL n sa1 $ Deep33 sa2 sa3 sa4 m ta1 ta2 (A.append n x y) shiftLA !n (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) !x !y = shriftL n sa1 $ Deep34 sa2 sa3 sa4 m ta1 ta2 ta3 (A.append n x y) shiftLA !n (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) !x !y = shriftL n sa1 $ Deep33 sa2 sa3 sa4 (snocA (Sz.twice (Sz.twice n)) m (A.append (Sz.twice n) ta1 ta2)) ta3 ta4 (A.append n x y) shriftL :: Size n -> Array (Twice n) a -> Deque (Twice n) a -> ShiftedL n a shriftL !n !sa d | (sa1, sa2) <- A.splitArray n sa = ShiftedL sa1 sa2 d shiftRA :: Size n -> Array n a -> Array n a -> Deque (Twice n) a -> ShiftedR n a shiftRA !_ !sa1 !sa2 Empty = ShiftedR Empty sa1 sa2 shiftRA n sa1 sa2 (Shallow ta) = shriftR n ta (Shallow (A.append n sa1 sa2)) shiftRA n x y (Deep11 sa1 m ta1) = shriftR n ta1 $ case viewRA (Sz.twice (Sz.twice n)) m of EmptyR -> Deep11 (A.append n x y) Empty sa1 SnocR m' me | (me1, me2) <- A.splitArray (Sz.twice n) me -> Deep22 (A.append n x y) sa1 m' me1 me2 shiftRA n x y (Deep12 sa1 m ta1 ta2) = shriftR n ta2 $ Deep21 (A.append n x y) sa1 m ta1 shiftRA n x y (Deep13 sa1 m ta1 ta2 ta3) = shriftR n ta3 $ Deep22 (A.append n x y) sa1 m ta1 ta2 shiftRA n x y (Deep14 sa1 m ta1 ta2 ta3 ta4) = shriftR n ta4 $ Deep23 (A.append n x y) sa1 m ta1 ta2 ta3 shiftRA n x y (Deep21 sa1 sa2 m ta1) = shriftR n ta1 $ case viewRA (Sz.twice (Sz.twice n)) m of EmptyR -> Deep21 (A.append n x y) sa1 Empty sa2 SnocR m' me | (me1, me2) <- A.splitArray (Sz.twice n) me -> Deep32 (A.append n x y) sa1 sa2 m' me1 me2 shiftRA n x y (Deep22 sa1 sa2 m ta1 ta2) = shriftR n ta2 $ Deep31 (A.append n x y) sa1 sa2 m ta1 shiftRA n x y (Deep23 sa1 sa2 m ta1 ta2 ta3) = shriftR n ta3 $ Deep32 (A.append n x y) sa1 sa2 m ta1 ta2 shiftRA n x y (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) = shriftR n ta4 $ Deep33 (A.append n x y) sa1 sa2 m ta1 ta2 ta3 shiftRA n x y (Deep31 sa1 sa2 sa3 m ta1) = shriftR n ta1 $ case shiftRA (Sz.twice n) sa2 sa3 m of ShiftedR m' me1 me2 -> Deep22 (A.append n x y) sa1 m' me1 me2 shiftRA n x y (Deep32 sa1 sa2 sa3 m ta1 ta2) = shriftR n ta2 $ Deep41 (A.append n x y) sa1 sa2 sa3 m ta1 shiftRA n x y (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) = shriftR n ta3 $ Deep42 (A.append n x y) sa1 sa2 sa3 m ta1 ta2 shiftRA n x y (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) = shriftR n ta4 $ Deep43 (A.append n x y) sa1 sa2 sa3 m ta1 ta2 ta3 shiftRA n x y (Deep41 sa1 sa2 sa3 sa4 m ta1) = shriftR n ta1 $ case shiftRA (Sz.twice n) sa3 sa4 m of ShiftedR m' me1 me2 -> Deep32 (A.append n x y) sa1 sa2 m' me1 me2 shiftRA n x y (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) = shriftR n ta2 $ case shiftRA (Sz.twice n) sa3 sa4 m of ShiftedR m' me1 me2 -> Deep33 (A.append n x y) sa1 sa2 m' me1 me2 ta1 shiftRA n x y (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) = shriftR n ta3 $ Deep32 (A.append n x y) sa1 sa2 (consA (Sz.twice (Sz.twice n)) (A.append (Sz.twice n) sa3 sa4) m) ta1 ta2 shiftRA n x y (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) = shriftR n ta4 $ Deep33 (A.append n x y) sa1 sa2 (consA (Sz.twice (Sz.twice n)) (A.append (Sz.twice n) sa3 sa4) m) ta1 ta2 ta3 shriftR :: Size n -> Array (Twice n) a -> Deque (Twice n) a -> ShiftedR n a shriftR !n !sa d | (sa1, sa2) <- A.splitArray n sa = ShiftedR d sa1 sa2 consSnocA :: Size n -> Array n a -> Deque n a -> Array n a -> Deque n a consSnocA !_ !sa1 Empty !sa2 = Deep11 sa1 Empty sa2 consSnocA !_ !sa1 (Shallow sa2) !sa3 = Deep21 sa1 sa2 Empty sa3 consSnocA !_ !x (Deep11 sa1 m ta1) !y = Deep22 x sa1 m ta1 y consSnocA !_ !x (Deep12 sa1 m ta1 ta2) !y = Deep23 x sa1 m ta1 ta2 y consSnocA !_ !x (Deep13 sa1 m ta1 ta2 ta3) !y = Deep24 x sa1 m ta1 ta2 ta3 y consSnocA !n !x (Deep14 sa1 m ta1 ta2 ta3 ta4) !y = Deep23 x sa1 (snocA (Sz.twice n) m (A.append n ta1 ta2)) ta3 ta4 y consSnocA !_ !x (Deep21 sa1 sa2 m ta1) !y = Deep32 x sa1 sa2 m ta1 y consSnocA !_ !x (Deep22 sa1 sa2 m ta1 ta2) !y = Deep33 x sa1 sa2 m ta1 ta2 y consSnocA !_ !x (Deep23 sa1 sa2 m ta1 ta2 ta3) !y = Deep34 x sa1 sa2 m ta1 ta2 ta3 y consSnocA !n !x (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) !y = Deep33 x sa1 sa2 (snocA (Sz.twice n) m (A.append n ta1 ta2)) ta3 ta4 y consSnocA !_ !x (Deep31 sa1 sa2 sa3 m ta1) !y = Deep42 x sa1 sa2 sa3 m ta1 y consSnocA !_ !x (Deep32 sa1 sa2 sa3 m ta1 ta2) !y = Deep43 x sa1 sa2 sa3 m ta1 ta2 y consSnocA !_ !x (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) !y = Deep44 x sa1 sa2 sa3 m ta1 ta2 ta3 y consSnocA !n !x (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) !y = Deep23 x sa1 (consSnocA (Sz.twice n) (A.append n sa2 sa3) m (A.append n ta1 ta2)) ta3 ta4 y consSnocA n !x (Deep41 sa1 sa2 sa3 sa4 m ta1) !y = Deep32 x sa1 sa2 (consA (Sz.twice n) (A.append n sa3 sa4) m) ta1 y consSnocA n !x (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) !y = Deep33 x sa1 sa2 (consA (Sz.twice n) (A.append n sa3 sa4) m) ta1 ta2 y consSnocA n !x (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) !y = Deep32 x sa1 sa2 (consSnocA (Sz.twice n) (A.append n sa3 sa4) m (A.append n ta1 ta2)) ta3 y consSnocA n !x (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) !y = Deep33 x sa1 sa2 (consSnocA (Sz.twice n) (A.append n sa3 sa4) m (A.append n ta1 ta2)) ta3 ta4 y data UCUS n a = EmptyUCUS | OneUCUS !(Array n a) | UCUS !(Array n a) (Deque n a) !(Array n a) unconsUnsnocA :: Size n -> Deque n a -> UCUS n a unconsUnsnocA !_ Empty = EmptyUCUS unconsUnsnocA !_ (Shallow sa) = OneUCUS sa unconsUnsnocA n (Deep11 sa1 m ta1) = flip (UCUS sa1) ta1 $ case unconsUnsnocA (Sz.twice n) m of EmptyUCUS -> Empty OneUCUS mm | (m1, m2) <- A.splitArray n mm -> Deep11 m1 Empty m2 UCUS mb m' me | (mb1, mb2) <- A.splitArray n mb , (me1, me2) <- A.splitArray n me -> Deep22 mb1 mb2 m' me1 me2 unconsUnsnocA n (Deep12 sa1 m ta1 ta2) = flip (UCUS sa1) ta2 $ case unconsUnsnocA (Sz.twice n) m of EmptyUCUS -> Shallow ta1 OneUCUS mm | (m1, m2) <- A.splitArray n mm -> Deep21 m1 m2 Empty ta1 UCUS mb m' me | (mb1, mb2) <- A.splitArray n mb , (me1, me2) <- A.splitArray n me -> Deep23 mb1 mb2 m' me1 me2 ta1 unconsUnsnocA n (Deep13 sa1 m ta1 ta2 ta3) = flip (UCUS sa1) ta3 $ case viewLA (Sz.twice n) m of EmptyL -> Deep11 ta1 Empty ta2 ConsL mb m' | (mb1, mb2) <- A.splitArray n mb -> Deep22 mb1 mb2 m' ta1 ta2 unconsUnsnocA n (Deep14 sa1 m ta1 ta2 ta3 ta4) = flip (UCUS sa1) ta4 $ case viewLA (Sz.twice n) m of EmptyL -> Deep12 ta1 Empty ta2 ta3 ConsL mb m' | (mb1, mb2) <- A.splitArray n mb -> Deep23 mb1 mb2 m' ta1 ta2 ta3 unconsUnsnocA !n (Deep21 sa1 sa2 m ta1) = flip (UCUS sa1) ta1 $ case unconsUnsnocA (Sz.twice n) m of EmptyUCUS -> Shallow sa2 OneUCUS mm | (m1, m2) <- A.splitArray n mm -> Deep21 sa2 m1 Empty m2 UCUS mb m' me | (mb1, mb2) <- A.splitArray n mb , (me1, me2) <- A.splitArray n me -> Deep32 sa2 mb1 mb2 m' me1 me2 unconsUnsnocA !_ (Deep22 sa1 sa2 m ta1 ta2) = UCUS sa1 (Deep11 sa2 m ta1) ta2 unconsUnsnocA !_ (Deep23 sa1 sa2 m ta1 ta2 ta3) = UCUS sa1 (Deep12 sa2 m ta1 ta2) ta3 unconsUnsnocA !_ (Deep24 sa1 sa2 m ta1 ta2 ta3 ta4) = UCUS sa1 (Deep13 sa2 m ta1 ta2 ta3) ta4 unconsUnsnocA !n (Deep31 sa1 sa2 sa3 m ta1) = flip (UCUS sa1) ta1 $ case viewRA (Sz.twice n) m of EmptyR -> Deep11 sa2 Empty sa3 SnocR m' me | (me1, me2) <- A.splitArray n me -> Deep22 sa2 sa3 m' me1 me2 unconsUnsnocA !_ (Deep32 sa1 sa2 sa3 m ta1 ta2) = UCUS sa1 (Deep21 sa2 sa3 m ta1) ta2 unconsUnsnocA !_ (Deep33 sa1 sa2 sa3 m ta1 ta2 ta3) = UCUS sa1 (Deep22 sa2 sa3 m ta1 ta2) ta3 unconsUnsnocA !_ (Deep34 sa1 sa2 sa3 m ta1 ta2 ta3 ta4) = UCUS sa1 (Deep23 sa2 sa3 m ta1 ta2 ta3) ta4 unconsUnsnocA !n (Deep41 sa1 sa2 sa3 sa4 m ta1) = flip (UCUS sa1) ta1 $ case viewRA (Sz.twice n) m of EmptyR -> Deep21 sa2 sa3 Empty sa4 SnocR m' me | (me1, me2) <- A.splitArray n me -> Deep32 sa2 sa3 sa4 m' me1 me2 unconsUnsnocA !_ (Deep42 sa1 sa2 sa3 sa4 m ta1 ta2) = UCUS sa1 (Deep31 sa2 sa3 sa4 m ta1) ta2 unconsUnsnocA !_ (Deep43 sa1 sa2 sa3 sa4 m ta1 ta2 ta3) = UCUS sa1 (Deep32 sa2 sa3 sa4 m ta1 ta2) ta3 unconsUnsnocA !_ (Deep44 sa1 sa2 sa3 sa4 m ta1 ta2 ta3 ta4) = UCUS sa1 (Deep33 sa2 sa3 sa4 m ta1 ta2 ta3) ta4 data Deque_ n a = Empty_ | Shallow_ !(Array n a) | Deep_ !(Digit n a) (Deque (Twice n) a) !(Digit n a) matchDeep :: Deque n a -> Deque_ n a matchDeep q = case q of Empty -> Empty_ Shallow sa -> Shallow_ sa Deep11 x m a -> Deep_ (One x) m (One a) Deep12 x m a b -> Deep_ (One x) m (Two a b) Deep13 x m a b c -> Deep_ (One x) m (Three a b c) Deep14 x m a b c d -> Deep_ (One x) m (Four a b c d) Deep21 x y m a -> Deep_ (Two x y) m (One a) Deep22 x y m a b -> Deep_ (Two x y) m (Two a b) Deep23 x y m a b c -> Deep_ (Two x y) m (Three a b c) Deep24 x y m a b c d -> Deep_ (Two x y) m (Four a b c d) Deep31 x y z m a -> Deep_ (Three x y z) m (One a) Deep32 x y z m a b -> Deep_ (Three x y z) m (Two a b) Deep33 x y z m a b c -> Deep_ (Three x y z) m (Three a b c) Deep34 x y z m a b c d -> Deep_ (Three x y z) m (Four a b c d) Deep41 x y z w m a -> Deep_ (Four x y z w) m (One a) Deep42 x y z w m a b -> Deep_ (Four x y z w) m (Two a b) Deep43 x y z w m a b c -> Deep_ (Four x y z w) m (Three a b c) Deep44 x y z w m a b c d -> Deep_ (Four x y z w) m (Four a b c d) {-# INLINE matchDeep #-} pattern Deep :: Digit n a -> Deque (Twice n) a -> Digit n a -> Deque n a pattern Deep pr m sf <- (matchDeep -> Deep_ pr m sf) where Deep (One x) m (One a) = Deep11 x m a Deep (One x) m (Two a b) = Deep12 x m a b Deep (One x) m (Three a b c) = Deep13 x m a b c Deep (One x) m (Four a b c d) = Deep14 x m a b c d Deep (Two x y) m (One a) = Deep21 x y m a Deep (Two x y) m (Two a b) = Deep22 x y m a b Deep (Two x y) m (Three a b c) = Deep23 x y m a b c Deep (Two x y) m (Four a b c d) = Deep24 x y m a b c d Deep (Three x y z) m (One a) = Deep31 x y z m a Deep (Three x y z) m (Two a b) = Deep32 x y z m a b Deep (Three x y z) m (Three a b c) = Deep33 x y z m a b c Deep (Three x y z) m (Four a b c d) = Deep34 x y z m a b c d Deep (Four x y z w) m (One a) = Deep41 x y z w m a Deep (Four x y z w) m (Two a b) = Deep42 x y z w m a b Deep (Four x y z w) m (Three a b c) = Deep43 x y z w m a b c Deep (Four x y z w) m (Four a b c d) = Deep44 x y z w m a b c d {-# COMPLETE Empty, Shallow, Deep #-} data Digit n a = One !(Array n a) | Two !(Array n a) !(Array n a) | Three !(Array n a) !(Array n a) !(Array n a) | Four !(Array n a) !(Array n a) !(Array n a) !(Array n a) -- Converts a list of sz * n elements to a deque. -- Unlike a queue, we *can't* convert incrementally, -- so there's not much use being polymorphic in the state -- monad. fromListNM :: Size sz -> Int -> State [a] (Deque sz a) fromListNM sz n = fromListNS sz (N.toBin45 n) fromListNS :: Size sz -> N.Bin45 -> State [a] (Deque sz a) fromListNS !_ N.End45 = pure Empty fromListNS sz N.OneEnd45 = do sa1 <- state (A.arraySplitListN sz) pure $! Shallow sa1 fromListNS sz N.TwoEnd45 = do sa1 <- state (A.arraySplitListN sz) sa2 <- state (A.arraySplitListN sz) pure $! Deep11 sa1 Empty sa2 fromListNS sz N.ThreeEnd45 = do sa1 <- state (A.arraySplitListN sz) sa2 <- state (A.arraySplitListN sz) sa3 <- state (A.arraySplitListN sz) pure $! Deep21 sa1 sa2 Empty sa3 fromListNS sz (N.Four45 n) = do sa1 <- state (A.arraySplitListN sz) sa2 <- state (A.arraySplitListN sz) m <- fromListNS (Sz.twice sz) n ta1 <- state (A.arraySplitListN sz) ta2 <- state (A.arraySplitListN sz) pure $ Deep22 sa1 sa2 m ta1 ta2 fromListNS sz (N.Five45 n) = do sa1 <- state (A.arraySplitListN sz) sa2 <- state (A.arraySplitListN sz) sa3 <- state (A.arraySplitListN sz) m <- fromListNS (Sz.twice sz) n ta1 <- state (A.arraySplitListN sz) ta2 <- state (A.arraySplitListN sz) pure $ Deep32 sa1 sa2 sa3 m ta1 ta2