diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 11d67b82027bbd9c1976068da2b796996ee055df323f0e38133562dfe9a669a4
+-- hash: 28b96617af1777ecd486d96708483a873f7ade860b7bcfa1ba5f666fde5ecd49
 
 name:           hw-prim
-version:        0.5.0.5
+version:        0.6.0.0
 synopsis:       Primitive functions and data types
 description:    Please see README.md
 category:       Data
diff --git a/src/HaskellWorks/Data/AtIndex.hs b/src/HaskellWorks/Data/AtIndex.hs
--- a/src/HaskellWorks/Data/AtIndex.hs
+++ b/src/HaskellWorks/Data/AtIndex.hs
@@ -7,10 +7,9 @@
     ( Container(..)
     , AtIndex(..)
     , Length(..)
-    , (?!?)
-    , (?!$)
     , atIndexOr
-    , atIndexOrLastOr
+    , atIndexOrBeforeOrAfter
+    , atIndexOrBeforeOrLast
     ) where
 
 import Data.Int
@@ -18,10 +17,9 @@
 import HaskellWorks.Data.Length
 import HaskellWorks.Data.Positioning
 
-import qualified Data.ByteString          as BS
-import qualified Data.Vector              as DV
-import qualified Data.Vector.Storable     as DVS
-import qualified HaskellWorks.Data.Length as HW
+import qualified Data.ByteString      as BS
+import qualified Data.Vector          as DV
+import qualified Data.Vector.Storable as DVS
 
 class Length v => AtIndex v where
   (!!!)     :: v -> Position -> Elem v
@@ -226,40 +224,34 @@
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
--- | Get the element of the container at the specified position, but return the  default value
--- `d` if the position is out of bounds.
-(?!?) :: AtIndex v => Elem v -> Elem v -> v -> Position -> Elem v
-(?!?) d e v vi = if vi >= 0
-  then if vi < end v
-    then v !!! vi
-    else e
-  else d
-{-# INLINE (?!?) #-}
-
--- | Get the element of the container at the specified position, but return the last element
--- if the position is past the end of the container or the default value `d` if the position
--- is before the beginning of the vector.
--- In the case when the container is empty, then the default value `d` is used.
-(?!$) :: (AtIndex v, Length v) => Elem v -> v -> Position -> Elem v
-(?!$) d v vi = if vi >= 0
-  then if vi < end v
-    then v !!! vi
-    else if end v == 0
-      then d
-      else v !!! (end v - 1)
-  else d
-{-# INLINE (?!$) #-}
-
+-- | Get the element of the container at the specified position, but return 'd' if position
+-- is out of bounds.
 atIndexOr :: AtIndex v => Elem v -> v -> Position -> Elem v
 atIndexOr d v vi = if vi >= 0 && vi < end v
   then v !!! vi
   else d
 {-# INLINE atIndexOr #-}
 
-atIndexOrLastOr :: AtIndex v => Elem v -> v -> Position -> Elem v
-atIndexOrLastOr d v vi = if vi >= 0 && HW.length v > 0
+-- | Get the element of the container at the specified position, but return 'before' if position
+-- before the first element or 'after' if the position is beyond the last element.
+atIndexOrBeforeOrAfter :: AtIndex v => Elem v -> Elem v -> v -> Position -> Elem v
+atIndexOrBeforeOrAfter before after v vi = if vi < end v
+  then if vi >= 0
+    then v !!! vi
+    else before
+  else after
+{-# INLINE atIndexOrBeforeOrAfter #-}
+
+-- | Get the element of the container at the specified position, but return the last element
+-- if the position is past the end of the container or the default value 'before'' if the position
+-- is before the beginning of the vector.
+-- In the case when the container is empty, then the default value 'before'' is used.
+atIndexOrBeforeOrLast :: (AtIndex v, Length v) => Elem v -> v -> Position -> Elem v
+atIndexOrBeforeOrLast before v vi = if vi >= 0
   then if vi < end v
     then v !!! vi
-    else v !!! (end v - 1)
-  else d
-{-# INLINE atIndexOrLastOr #-}
+    else if end v /= 0
+      then v !!! (end v - 1)
+      else before
+  else before
+{-# INLINE atIndexOrBeforeOrLast #-}
