packages feed

sdp-0.2: src/SDP/Templates/AnyBorder.hs

{-# LANGUAGE TypeFamilies, DeriveDataTypeable, DeriveGeneric, TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
{-# LANGUAGE Trustworthy, UndecidableInstances #-}

{- |
    Module      :  SDP.Templates.AnyBorder
    Copyright   :  (c) Andrey Mulik 2020
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  non-portable (GHC extensions)
    
    "SDP.Plate.AnyBorder" provides 'AnyBorder' - template of generalized by
    index type structure, based on 'Int'-indexed primitive.
-}
module SDP.Templates.AnyBorder
(
  -- * Export
  module SDP.IndexedM,
  module SDP.Shaped,
  module SDP.Sort,
  module SDP.Scan,
  
  -- * Border template
  AnyBorder (..)
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.IndexedM
import SDP.Shaped
import SDP.SortM
import SDP.Sort
import SDP.Scan

import Data.Default.Class
import Data.Typeable
import Data.String
import Data.Data

import Text.Read.SDP
import Text.Show.SDP

import GHC.Generics
import qualified GHC.Exts as E

import Control.Exception.SDP

default ()

--------------------------------------------------------------------------------

{- |
  'AnyBorder' is template, that appends arbitrary bounds to any structure.
  
  * 'Eq', 'Ord', 'Eq1' and 'Ord1' instances ingores bounds.
  * 'Thaw' and 'Freeze' instances for @'AnyBorder' rep e@ inherit @rep e@
  behavior.
-}
data AnyBorder rep i e = AnyBorder !i !i !(rep e)
  deriving ( Typeable, Data, Generic )

--------------------------------------------------------------------------------

{- Eq ad Eq1 instances. -}

instance (Index i, Eq (rep e)) => Eq (AnyBorder rep i e)
  where
    (==) = on (==) unpack

instance (Index i, Eq1 rep) => Eq1 (AnyBorder rep i)
  where
    liftEq f xs ys = liftEq f (unpack xs) (unpack ys)

--------------------------------------------------------------------------------

{- Ord and Ord1 instances. -}

instance (Index i, Ord (rep e)) => Ord (AnyBorder rep i e)
  where
    compare = on (<=>) unpack

instance (Index i, Ord1 rep) => Ord1 (AnyBorder rep i)
  where
    liftCompare f xs ys = liftCompare f (unpack xs) (unpack ys)

--------------------------------------------------------------------------------

{- Show and Read instances. -}

instance {-# OVERLAPPABLE #-} (Indexed1 rep Int e, Index i, Show i, Show e) => Show (AnyBorder rep i e)
  where
    showsPrec = assocsPrec "array "

instance (Indexed1 rep Int Char, Index i, Show i) => Show (AnyBorder rep i Char)
  where
    showsPrec = shows ... const listL

instance (Index i, Read i, Read e, Indexed1 rep Int e) => Read (AnyBorder rep i e)
  where
    readPrec = indexedPrec' "array"
    readList = readListDefault

--------------------------------------------------------------------------------

{- Overloaded Lists and String support. -}

instance (Index i, IsString (rep Char), Bordered1 rep Int Char) => IsString (AnyBorder rep i Char)
  where
    fromString = withBounds . fromString

instance (Index i, E.IsList (rep e), Bordered1 rep Int e) => E.IsList (AnyBorder rep i e)
  where
    type Item (AnyBorder rep i e) = E.Item (rep e)
    
    fromListN = withBounds ... E.fromListN
    fromList  = withBounds . E.fromList
    toList    = E.toList . unpack

--------------------------------------------------------------------------------

{- Semigroup, Monoid, Nullable, Default and Estimate instances. -}

instance (Index i, Bordered (rep e) Int, Nullable (rep e)) => Nullable (AnyBorder rep i e)
  where
    isNull = \ (AnyBorder l u rep) -> isEmpty (l, u) || isNull rep
    lzero  = withBounds lzero

instance (Linear1 (AnyBorder rep i) e) => Semigroup (AnyBorder rep i e) where (<>) = (++)
instance (Linear1 (AnyBorder rep i) e) => Monoid    (AnyBorder rep i e) where mempty = Z
instance (Linear1 (AnyBorder rep i) e) => Default   (AnyBorder rep i e) where def = Z

instance (Index i) => Estimate (AnyBorder rep i e)
  where
    (<==>) = on (<=>) sizeOf
    (.<=.) = on (<=)  sizeOf
    (.>=.) = on (>=)  sizeOf
    (.>.)  = on (>)   sizeOf
    (.<.)  = on (<)   sizeOf
    
    (<.=>) = (<=>) . sizeOf
    (.>=)  = (>=)  . sizeOf
    (.<=)  = (<=)  . sizeOf
    (.>)   = (>)   . sizeOf
    (.<)   = (<)   . sizeOf

--------------------------------------------------------------------------------

{- Functor, Zip and Applicative instances. -}

instance (Index i, Functor rep) => Functor (AnyBorder rep i)
  where
    fmap f (AnyBorder l u rep) = AnyBorder l u (f <$> rep)

instance (Index i, Zip rep) => Zip (AnyBorder rep i)
  where
    all2 f as bs             = all2 f (unpack as) (unpack bs)
    all3 f as bs cs          = all3 f (unpack as) (unpack bs) (unpack cs)
    all4 f as bs cs ds       = all4 f (unpack as) (unpack bs) (unpack cs) (unpack ds)
    all5 f as bs cs ds es    = all5 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es)
    all6 f as bs cs ds es fs = all6 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es) (unpack fs)
    
    any2 f as bs             = any2 f (unpack as) (unpack bs)
    any3 f as bs cs          = any3 f (unpack as) (unpack bs) (unpack cs)
    any4 f as bs cs ds       = any4 f (unpack as) (unpack bs) (unpack cs) (unpack ds)
    any5 f as bs cs ds es    = any5 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es)
    any6 f as bs cs ds es fs = any6 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es) (unpack fs)
    
    zipWith f as bs =
      let (l, u) = defaultBounds $ minimum [sizeOf as, sizeOf bs]
      in  AnyBorder l u $ zipWith f (unpack as) (unpack bs)
    
    zipWith3 f as bs cs =
      let (l, u) = defaultBounds $ minimum [sizeOf as, sizeOf bs, sizeOf cs]
      in  AnyBorder l u $ zipWith3 f (unpack as) (unpack bs) (unpack cs)
    
    zipWith4 f as bs cs ds =
      let (l, u) = defaultBounds $ minimum [sizeOf as, sizeOf bs, sizeOf cs, sizeOf ds]
      in  AnyBorder l u $ zipWith4 f (unpack as) (unpack bs) (unpack cs) (unpack ds)
    
    zipWith5 f as bs cs ds es =
      let (l, u) = defaultBounds $ minimum [sizeOf as, sizeOf bs, sizeOf cs, sizeOf ds, sizeOf es]
      in  AnyBorder l u $ zipWith5 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es)
    
    zipWith6 f as bs cs ds es fs =
      let (l, u) = defaultBounds $ minimum [sizeOf as, sizeOf bs, sizeOf cs, sizeOf ds, sizeOf es, sizeOf fs]
      in  AnyBorder l u $ zipWith6 f (unpack as) (unpack bs) (unpack cs) (unpack ds) (unpack es) (unpack fs)

instance (Index i, Applicative rep) => Applicative (AnyBorder rep i)
  where
    pure = uncurry AnyBorder (defaultBounds 1) . pure
    
    (AnyBorder lf uf fs) <*> (AnyBorder le ue es) =
      let (l, u) = defaultBounds (size (lf, uf) * size (le, ue))
      in  AnyBorder l u (fs <*> es)

--------------------------------------------------------------------------------

{- Foldable and Traversable instances. -}

instance (Index i, Foldable rep) => Foldable (AnyBorder rep i)
  where
    foldr  f base = foldr  f base . unpack
    foldl  f base = foldl  f base . unpack
    foldr' f base = foldr' f base . unpack
    foldl' f base = foldl' f base . unpack
    
    foldr1 f = foldr1 f . unpack
    foldl1 f = foldl1 f . unpack
    
    length = length . unpack
    toList = toList . unpack
    null   = null   . unpack

instance (Index i, Traversable rep) => Traversable (AnyBorder rep i)
  where
    traverse f (AnyBorder l u es) = AnyBorder l u <$> traverse f es

--------------------------------------------------------------------------------

{- Bordered, Linear and Split instances. -}

instance (Index i) => Bordered (AnyBorder rep i e) i
  where
    lower    (AnyBorder l _ _) = l
    upper    (AnyBorder _ u _) = u
    bounds   (AnyBorder l u _) = (l, u)
    sizeOf   (AnyBorder l u _) = size    (l, u)
    indices  (AnyBorder l u _) = range   (l, u)
    indexOf  (AnyBorder l u _) = index   (l, u)
    indexIn  (AnyBorder l u _) = inRange (l, u)
    offsetOf (AnyBorder l u _) = offset  (l, u)

instance (Index i, Linear1 rep e, Bordered1 rep Int e) => Linear (AnyBorder rep i e) e
  where
    single = withBounds . single
    
    toHead e es = withBounds (e :> unpack es)
    toLast es e = withBounds (unpack es :< e)
    
    head = head . unpack
    last = last . unpack
    tail = withBounds . tail . unpack
    init = withBounds . init . unpack
    
    fromList  = fromFoldable
    fromListN = withBounds ... fromListN
    replicate = withBounds ... replicate
    iterate n = withBounds ... iterate n
    
    fromFoldable = withBounds . fromFoldable
    
    listL = listL . unpack
    listR = listR . unpack
    
    {-# INLINE (!^) #-}
    (!^) = (!^) . unpack
    (++) = withBounds ... on (++) unpack
    
    write (AnyBorder l u es) n e = AnyBorder l u (write es n e)
    
    concatMap = withBounds ... concatMap . (unpack .)
    concat    = withBounds  .  concatMap unpack
    
    partitions  f = fmap fromList . partitions f . listL
    intersperse e = withBounds . intersperse e . unpack
    
    filter f = withBounds . filter f . unpack
    
    reverse (AnyBorder l u rep) = AnyBorder l u (reverse rep)
    force   (AnyBorder l u rep) = AnyBorder l u (force   rep)
    
    select   f = select f . unpack
    extract  f = second withBounds . extract  f . unpack
    selects fs = second withBounds . selects fs . unpack
    
    nubBy f = withBounds . nubBy f . unpack
    nub     = withBounds .   nub   . unpack
    
    ofoldr f base = ofoldr f base . unpack
    ofoldl f base = ofoldl f base . unpack
    
    o_foldr f base = o_foldr f base . unpack
    o_foldl f base = o_foldl f base . unpack

instance (Index i, Split1 rep e, Bordered1 rep Int e) => Split (AnyBorder rep i e) e
  where
    take n = withBounds . take n . unpack
    drop n = withBounds . drop n . unpack
    keep n = withBounds . keep n . unpack
    sans n = withBounds . sans n . unpack
    
    splits ns = fmap withBounds . splits ns . unpack
    chunks ns = fmap withBounds . chunks ns . unpack
    parts  ns = fmap withBounds . parts  ns . unpack
    
    justifyL n e = withBounds . justifyL n e . unpack
    justifyR n e = withBounds . justifyR n e . unpack
    
    isPrefixOf xs ys = xs .<=. ys && on isPrefixOf unpack xs ys
    isSuffixOf xs ys = xs .<=. ys && on isSuffixOf unpack xs ys
    
    prefix p = prefix p . unpack
    suffix p = suffix p . unpack

--------------------------------------------------------------------------------

{- BorderedM, LinearM and SplitM instances. -}

instance (Index i, BorderedM1 m rep Int e) => BorderedM m (AnyBorder rep i e) i
  where
    nowIndexIn (AnyBorder l u _) = return . inRange (l, u)
    getIndices (AnyBorder l u _) = return $ range (l, u)
    getSizeOf  (AnyBorder l u _) = return $ size (l, u)
    getBounds  (AnyBorder l u _) = return (l, u)
    getLower   (AnyBorder l _ _) = return l
    getUpper   (AnyBorder _ u _) = return u

instance (Index i, LinearM1 m rep e, BorderedM1 m rep Int e) => LinearM m (AnyBorder rep i e) e
  where
    newNull = uncurry AnyBorder (defaultBounds 0) <$> newNull
    
    nowNull (AnyBorder l u es) = isEmpty (l, u) ? return True $ nowNull es
    
    getHead = getHead . unpack
    getLast = getLast . unpack
    
    prepend e = withBounds' <=< prepend e . unpack
    append es = withBounds' <=< append (unpack es)
    
    newLinear = withBounds' <=< newLinear
    filled  n = withBounds' <=< filled n
    
    getLeft   = getLeft  . unpack
    getRight  = getRight . unpack
    
    {-# INLINE (!#>) #-}
    (!#>) = (!#>) . unpack
    
    {-# INLINE writeM #-}
    writeM = writeM . unpack
    
    copied   (AnyBorder l u es) = AnyBorder l u <$> copied  es
    copied'  (AnyBorder l u es) = (AnyBorder l u <$>) ... copied' es
    reversed (AnyBorder l u es) = AnyBorder l u <$> reversed es
    
    copyTo src os trg ot = copyTo (unpack src) os (unpack trg) ot
    
    ofoldrM f e = ofoldrM f e . unpack
    ofoldlM f e = ofoldlM f e . unpack
    
    foldrM f e = foldrM f e . unpack
    foldlM f e = foldlM f e . unpack

instance (Index i, BorderedM1 m rep Int e, SplitM1 m rep e) => SplitM m (AnyBorder rep i e) e
  where
    takeM n es@(AnyBorder l u rep)
        | n <= 0 = newNull
        | n >= c = return es
        |  True  = AnyBorder l (index (l, u) n) <$> takeM n rep
      where
        c = size (l, u)
    
    dropM n es@(AnyBorder l u rep)
        | n >= c = newNull
        | n <= 0 = return es
        |  True  = AnyBorder (index (l, u) n) u <$> dropM n rep
      where
        c = size (l, u)
    
    keepM n es@(AnyBorder l u rep)
        | n <= 0 = newNull
        | n >= c = return es
        |  True  = AnyBorder (index (l, u) (c - n)) u <$> keepM n rep
      where
        c = size (l, u)
    
    sansM n es@(AnyBorder l u rep)
        | n >= c = newNull
        | n <= 0 = return es
        |  True  = AnyBorder (index (l, u) (c - n)) u <$> sansM n rep
      where
        c = size (l, u)
    
    splitM n es@(AnyBorder l u rep)
        | n <= 0 = do e' <- newNull; return (e', es)
        | n >= c = do e' <- newNull; return (es, e')
        |  True  = bimap (AnyBorder l i) (AnyBorder i u) <$> splitM n rep
      where
        i = index (l, u) n
        c = size  (l, u)
    
    divideM n es@(AnyBorder l u rep)
        | n <= 0 = do e' <- newNull; return (es, e')
        | n >= c = do e' <- newNull; return (e', es)
        |  True  = bimap (AnyBorder l i) (AnyBorder i u) <$> divideM n rep
      where
        i = index (l, u) (c - n)
        c = size  (l, u)
    
    prefixM p = prefixM p . unpack
    suffixM p = suffixM p . unpack
    mprefix p = mprefix p . unpack
    msuffix p = msuffix p . unpack

--------------------------------------------------------------------------------

{- Set, Scan and Sort instances. -}

instance (SetWith1 (AnyBorder rep i) e, Nullable (AnyBorder rep i e), Ord e) => Set (AnyBorder rep i e) e

instance (Index i, SetWith1 rep e, Linear1 rep e, Bordered1 rep Int e) => SetWith (AnyBorder rep i e) e
  where
    isSubsetWith f = isSubsetWith f `on` unpack
    
    setWith f = withBounds . setWith f . unpack
    
    subsets = map withBounds . subsets . unpack
    
    insertWith f e = withBounds . insertWith f e . unpack
    deleteWith f e = withBounds . deleteWith f e . unpack
    
    intersectionWith f = withBounds ... on (intersectionWith f) unpack
    unionWith        f = withBounds ... on (unionWith        f) unpack
    differenceWith   f = withBounds ... on (differenceWith   f) unpack
    symdiffWith      f = withBounds ... on (symdiffWith      f) unpack
    
    memberWith   f e = memberWith   f e . unpack
    lookupLTWith f o = lookupLTWith f o . unpack
    lookupGTWith f o = lookupGTWith f o . unpack
    lookupLEWith f o = lookupLEWith f o . unpack
    lookupGEWith f o = lookupGEWith f o . unpack

instance (Linear1 (AnyBorder rep i) e) => Scan (AnyBorder rep i e) e

instance (Index i, Sort (rep e) e) => Sort (AnyBorder rep i e) e
  where
    sortBy cmp = \ (AnyBorder l u rep) -> AnyBorder l u (sortBy cmp rep)
    sortedBy f = sortedBy f . unpack

--------------------------------------------------------------------------------

{- Map, Indexed and Shaped instances. -}

instance (Index i, Indexed1 rep Int e) => Map (AnyBorder rep i e) i e
  where
    toMap ascs = isNull ascs ? Z $ assoc (ascsBounds ascs) ascs
    
    toMap' e ascs = isNull ascs ? Z $ assoc' (ascsBounds ascs) e ascs
    
    {-# INLINE (.!) #-}
    (.!) (AnyBorder l u rep) = (rep !^) . offset (l, u)
    
    Z // ascs = toMap ascs
    (AnyBorder l u rep) // ascs =
      let ies = [ (offset (l, u) i, e) | (i, e) <- ascs, inRange (l, u) i ]
      in  AnyBorder l u (rep // ies)
    
    p .$ (AnyBorder l u rep) = index (l, u) <$> p .$ rep
    p *$ (AnyBorder l u rep) = index (l, u) <$> p *$ rep
    
    kfoldr f base (AnyBorder l u es) = kfoldr (f . index (l, u)) base es
    kfoldl f base (AnyBorder l u es) = kfoldl (f . index (l, u)) base es

instance (Index i, Indexed1 rep Int e) => Indexed (AnyBorder rep i e) i e
  where
    assoc bnds@(l, u) ascs = AnyBorder l u (assoc bnds' ies)
      where
        ies   = [ (offset bnds i, e) | (i, e) <- ascs, inRange bnds i ]
        bnds' = defaultBounds (size bnds)
    
    assoc' bnds@(l, u) defvalue ascs = AnyBorder l u (assoc' bnds' defvalue ies)
      where
        ies   = [ (offset bnds i, e) | (i, e) <- ascs, inRange bnds i ]
        bnds' = defaultBounds $ size bnds
    
    fromIndexed = withBounds . fromIndexed

instance (Bordered1 rep Int e, Split1 rep e) => Shaped (AnyBorder rep) e
  where
    reshape es bs = size bs >. es ? expEx "reshape" $ uncurry AnyBorder bs (unpack es)
    
    (AnyBorder l u rep) !! ij = uncurry AnyBorder sub . take s $ drop o rep
      where
        (num, sub) = slice (l, u) ij
        
        o = offset num ij * s
        s = size sub
    
    slices es =
      let bnds = both takeDim (bounds es)
      in  uncurry AnyBorder bnds <$> size bnds `chunks` unpack es
    
    unslice ess =
      let bnds = defaultBounds (foldr' ((+) . sizeOf) 0 ess)
      in  uncurry AnyBorder bnds (concatMap unpack ess)

--------------------------------------------------------------------------------

{- MapM, IndexedM and SortM instances. -}

instance (Index i, MapM1 m rep Int e, LinearM1 m rep e, BorderedM1 m rep Int e) => MapM m (AnyBorder rep i e) i e
  where
    newMap ascs =
      let bnds@(l, u) = ascsBounds ascs
      in  AnyBorder l u <$> newMap [ (offset bnds i, e) | (i, e) <- ascs ]
    
    newMap' defvalue ascs =
      let bnds@(l, u) = ascsBounds ascs
      in  AnyBorder l u <$> newMap' defvalue [ (offset bnds i, e) | (i, e) <- ascs ]
    
    {-# INLINE (>!) #-}
    (>!) (AnyBorder l u es) = (es !#>) . offset (l, u)
    
    overwrite es [] = return es
    overwrite (AnyBorder l u es) ascs =
      let ies = [ (offset (l, u) i, e) | (i, e) <- ascs, inRange (l, u) i ]
      in  isEmpty (l, u) ? newMap ascs $ AnyBorder l u <$> overwrite es ies
    
    kfoldrM f base (AnyBorder l u es) = ofoldrM (f . index (l, u)) base es
    kfoldlM f base (AnyBorder l u es) = ofoldlM (f . index (l, u)) base es

instance (Index i, IndexedM1 m rep Int e) => IndexedM m (AnyBorder rep i e) i e
  where
    fromAssocs (l, u) ascs = AnyBorder l u <$> fromAssocs bnds ies
      where
        ies  = [ (offset (l, u) i, e) | (i, e) <- ascs, inRange (l, u) i ]
        bnds = (0, size  (l, u) - 1)
    
    fromAssocs' (l, u) defvalue ascs = AnyBorder l u <$> fromAssocs' bnds defvalue ies
      where
        ies  = [ (offset (l, u) i, e) | (i, e) <- ascs, inRange (l, u) i ]
        bnds = (0, size (l, u) - 1)
    
    {-# INLINE writeM' #-}
    writeM' (AnyBorder l u es) = writeM' es . offset (l, u)
    
    fromIndexed' = withBounds' <=< fromIndexed'
    fromIndexedM = withBounds' <=< fromIndexedM

instance (Index i, SortM1 m rep e) => SortM m (AnyBorder rep i e) e
  where
    sortedMBy f = sortedMBy f . unpack
    sortMBy   f = sortMBy   f . unpack

--------------------------------------------------------------------------------

{- Freeze and Thaw instances. -}

-- Bordered (with any index) to prim.
instance {-# OVERLAPPABLE #-} (Index i, Thaw m (rep e) mut) => Thaw m (AnyBorder rep i e) mut
  where
    unsafeThaw = unsafeThaw . unpack
    thaw       = thaw . unpack

-- Prim to bordered (with any index).
instance {-# OVERLAPPABLE #-} (Index i, Thaw m imm (rep e), Bordered1 rep Int e) => Thaw m imm (AnyBorder rep i e)
  where
    unsafeThaw = fmap withBounds . unsafeThaw
    thaw       = fmap withBounds . thaw

-- Lift prim to prim on bordered on bordered (with same index).
instance {-# OVERLAPS #-} (Index i, Thaw1 m imm mut e) => Thaw m (AnyBorder imm i e) (AnyBorder mut i e)
  where
    unsafeThaw (AnyBorder l u imm) = AnyBorder l u <$> unsafeThaw imm
    thaw       (AnyBorder l u imm) = AnyBorder l u <$> thaw imm

-- Bordered (with any index) to prim.
instance {-# OVERLAPPABLE #-} (Index i, Freeze m (rep e) imm) => Freeze m (AnyBorder rep i e) imm
  where
    unsafeFreeze = unsafeFreeze . unpack
    freeze       = freeze . unpack

-- Prim to bordered (with any index).
instance {-# OVERLAPPABLE #-} (Index i, Freeze m mut (rep e), Bordered1 rep Int e) => Freeze m mut (AnyBorder rep i e)
  where
    unsafeFreeze = fmap withBounds . unsafeFreeze
    freeze       = fmap withBounds . freeze

-- Lift prim to prim on bordered to bordered (with same index).
instance {-# OVERLAPS #-} (Index i, Freeze1 m mut imm e) => Freeze m (AnyBorder mut i e) (AnyBorder imm i e)
  where
    unsafeFreeze (AnyBorder l u mut) = AnyBorder l u <$> unsafeFreeze mut
    freeze       (AnyBorder l u mut) = AnyBorder l u <$> freeze mut

--------------------------------------------------------------------------------

expEx :: String -> a
expEx =  throw . UnacceptableExpansion . showString "in SDP.Templates.AnyBorder."

ascsBounds :: (Ord a) => [(a, b)] -> (a, a)
ascsBounds =  \ ((x, _) : xs) -> foldr (\ (e, _) (mn, mx) -> (min mn e, max mx e)) (x, x) xs

{-# INLINE unpack #-}
unpack :: AnyBorder rep i e -> rep e
unpack =  \ (AnyBorder _ _ es) -> es

{-# INLINE withBounds #-}
withBounds :: (Index i, Bordered1 rep Int e) => rep e -> AnyBorder rep i e
withBounds rep = uncurry AnyBorder (defaultBounds $ sizeOf rep) rep

{-# INLINE withBounds' #-}
withBounds' :: (Index i, BorderedM1 m rep Int e) => rep e -> m (AnyBorder rep i e)
withBounds' rep = (\ n -> uncurry AnyBorder (defaultBounds n) rep) <$> getSizeOf rep