    {-# LANGUAGE TypeOperators #-}

    -- | An implementation of a zipper-like non-empty list structure that tracks
    --   an index position in the list (the 'focus').
    module Data.List.PointedList where

    import Prelude hiding (foldl, foldr, elem)

    import Control.Applicative
    import Control.Monad
    import Data.Binary
    import Data.Foldable hiding (find)
    import Data.List hiding (length, foldl, foldr, find, elem)
    import qualified Data.List as List
    import Data.Traversable

    -- | The implementation of the pointed list structure which tracks the current
    --   position in the list structure.
    data PointedList a = PointedList
      { forall a. PointedList a -> [a]
    _reversedPrefix :: [a]
      , forall a. PointedList a -> a
    _focus          :: a
      , forall a. PointedList a -> [a]
    _suffix         :: [a]
      } deriving (PointedList a -> PointedList a -> Bool
    (PointedList a -> PointedList a -> Bool)
    -> (PointedList a -> PointedList a -> Bool) -> Eq (PointedList a)
    forall a. Eq a => PointedList a -> PointedList a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => PointedList a -> PointedList a -> Bool
    == :: PointedList a -> PointedList a -> Bool
    $c/= :: forall a. Eq a => PointedList a -> PointedList a -> Bool
    /= :: PointedList a -> PointedList a -> Bool
    Eq)

    instance Binary a => Binary (PointedList a) where
      put :: PointedList a -> Put
    put (PointedList [a]
    x1 a
    x2 [a]
    x3) = do [a] -> Put
    forall t. Binary t => t -> Put
    put [a]
    x1; a -> Put
    forall t. Binary t => t -> Put
    put a
    x2; [a] -> Put
    forall t. Binary t => t -> Put
    put [a]
    x3
      get :: Get (PointedList a)
    get = do ([a] -> a -> [a] -> PointedList a)
    -> Get [a] -> Get a -> Get [a] -> Get (PointedList a)
    forall (m :: * -> *) a1 a2 a3 r.
    Monad m =>
    (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
    liftM3 [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList Get [a]
    forall t. Binary t => Get t
    get Get a
    forall t. Binary t => Get t
    get Get [a]
    forall t. Binary t => Get t
    get

    -- | Lens compatible with Control.Lens.
    reversedPrefix :: Functor f => ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    reversedPrefix :: forall (f :: * -> *) a.
    Functor f =>
    ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    reversedPrefix [a] -> f [a]
    f (PointedList [a]
    ls a
    x [a]
    rs) = (\[a]
    ls' -> [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls' a
    x [a]
    rs) ([a] -> PointedList a) -> f [a] -> f (PointedList a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [a] -> f [a]
    f [a]
    ls

    -- | Lens compatible with Control.Lens.
    focus :: Functor f => (a -> f a) -> PointedList a -> f (PointedList a)
    focus :: forall (f :: * -> *) a.
    Functor f =>
    (a -> f a) -> PointedList a -> f (PointedList a)
    focus a -> f a
    f (PointedList [a]
    ls a
    x [a]
    rs) = (\a
    x' -> [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    x' [a]
    rs) (a -> PointedList a) -> f a -> f (PointedList a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f a
    f a
    x

    -- | Lens compatible with Control.Lens.
    suffix :: Functor f => ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    suffix :: forall (f :: * -> *) a.
    Functor f =>
    ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    suffix [a] -> f [a]
    f (PointedList [a]
    ls a
    x [a]
    rs) = (\[a]
    rs' -> [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    x [a]
    rs') ([a] -> PointedList a) -> f [a] -> f (PointedList a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [a] -> f [a]
    f [a]
    rs

    -- | Lens compatible with Control.Lens.
    -- Internally reversing the prefix list.
    prefix :: Functor f => ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    prefix :: forall (f :: * -> *) a.
    Functor f =>
    ([a] -> f [a]) -> PointedList a -> f (PointedList a)
    prefix [a] -> f [a]
    f (PointedList [a]
    ls a
    x [a]
    rs) = (\[a]
    ls' -> [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    ls') a
    x [a]
    rs) ([a] -> PointedList a) -> f [a] -> f (PointedList a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [a] -> f [a]
    f ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    ls)

    instance (Show a) => Show (PointedList a) where
     show :: PointedList a -> String
    show (PointedList [a]
    ls a
    x [a]
    rs) = [a] -> String
    forall a. Show a => a -> String
    show ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    ls) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    x String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [a] -> String
    forall a. Show a => a -> String
    show [a]
    rs

    instance Functor PointedList where
     fmap :: forall a b. (a -> b) -> PointedList a -> PointedList b
    fmap a -> b
    f (PointedList [a]
    ls a
    x [a]
    rs) = [b] -> b -> [b] -> PointedList b
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList ((a -> b) -> [a] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> b
    f [a]
    ls) (a -> b
    f a
    x) ((a -> b) -> [a] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> b
    f [a]
    rs)

    instance Foldable PointedList where
     foldr :: forall a b. (a -> b -> b) -> b -> PointedList a -> b
    foldr a -> b -> b
    f b
    z (PointedList [a]
    ls a
    x [a]
    rs) = (b -> a -> b) -> b -> [a] -> b
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl ((a -> b -> b) -> b -> a -> b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip a -> b -> b
    f) ((a -> b -> b) -> b -> [a] -> b
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr a -> b -> b
    f b
    z (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    rs)) [a]
    ls

    instance Traversable PointedList where
     traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> PointedList a -> f (PointedList b)
    traverse a -> f b
    f (PointedList [a]
    ls a
    x [a]
    rs) = [b] -> b -> [b] -> PointedList b
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList ([b] -> b -> [b] -> PointedList b)
    -> f [b] -> f (b -> [b] -> PointedList b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
        ([b] -> [b]
    forall a. [a] -> [a]
    reverse ([b] -> [b]) -> f [b] -> f [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (a -> f b) -> [a] -> f [b]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse a -> f b
    f ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    ls)) f (b -> [b] -> PointedList b) -> f b -> f ([b] -> PointedList b)
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> a -> f b
    f a
    x f ([b] -> PointedList b) -> f [b] -> f (PointedList b)
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (a -> f b) -> [a] -> f [b]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse a -> f b
    f [a]
    rs

    -- | Create a 'PointedList' with a single element.
    singleton :: a -> PointedList a
    singleton :: forall a. a -> PointedList a
    singleton a
    x = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [] a
    x []

    -- | Possibly create a @'Just' 'PointedList'@ if the provided list has at least
    --   one element; otherwise, return Nothing.
    --
    --   The provided list's head will be the focus of the list, and the rest of
    --   list will follow on the right side.
    fromList :: [a] -> Maybe (PointedList a)
    fromList :: forall a. [a] -> Maybe (PointedList a)
    fromList []     = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    fromList (a
    x:[a]
    xs) = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [] a
    x [a]
    xs

    -- | Possibly create a @'Just' 'PointedList'@ if the provided list has at least
    --   one element; otherwise, return Nothing.
    --
    --   The provided list's last element will be the focus of the list, following
    --   the rest of the list in order, to the left.
    fromListEnd :: [a] -> Maybe (PointedList a)
    fromListEnd :: forall a. [a] -> Maybe (PointedList a)
    fromListEnd [] = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    fromListEnd [a]
    xs = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    xs' a
    x []
     where (a
    x:[a]
    xs') = [a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    xs

    -- | Replace the focus of the list, retaining the prefix and suffix.
    replace :: a -> PointedList a -> PointedList a
    replace :: forall a. a -> PointedList a -> PointedList a
    replace a
    x (PointedList [a]
    ls a
    _ [a]
    rs) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    x [a]
    rs
    -- replace = set focus

    -- | Possibly move the focus to the next element in the list.
    next :: PointedList a -> Maybe (PointedList a)
    next :: forall a. PointedList a -> Maybe (PointedList a)
    next (PointedList [a]
    _  a
    _ []) = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    next PointedList a
    p = (PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> (PointedList a -> PointedList a)
    -> PointedList a
    -> Maybe (PointedList a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PointedList a -> PointedList a
    forall a. PointedList a -> PointedList a
    tryNext) PointedList a
    p -- GHC doesn't allow PL form here

    -- | Attempt to move the focus to the next element, or 'error' if there are
    --   no more elements.
    tryNext :: PointedList a -> PointedList a
    tryNext :: forall a. PointedList a -> PointedList a
    tryNext p :: PointedList a
    p@(PointedList [a]
    _  a
    _ []    ) = String -> PointedList a
    forall a. HasCallStack => String -> a
    error String
    "cannot move to next element"
    tryNext   (PointedList [a]
    ls a
    x (a
    r:[a]
    rs)) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    ls) a
    r [a]
    rs

    -- | Possibly move the focus to the previous element in the list.
    previous :: PointedList a -> Maybe (PointedList a)
    previous :: forall a. PointedList a -> Maybe (PointedList a)
    previous (PointedList [] a
    _ [a]
    _ ) = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    previous PointedList a
    p = (PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> (PointedList a -> PointedList a)
    -> PointedList a
    -> Maybe (PointedList a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PointedList a -> PointedList a
    forall a. PointedList a -> PointedList a
    tryPrevious) PointedList a
    p

    -- | Attempt to move the focus to the previous element, or 'error' if there are
    --   no more elements.
    tryPrevious :: PointedList a -> PointedList a
    tryPrevious :: forall a. PointedList a -> PointedList a
    tryPrevious p :: PointedList a
    p@(PointedList []     a
    _ [a]
    _ ) =
      String -> PointedList a
    forall a. HasCallStack => String -> a
    error String
    "cannot move to previous element"
    tryPrevious   (PointedList (a
    l:[a]
    ls) a
    x [a]
    rs) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    l (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    rs)

    -- | An alias for 'insertRight'.
    insert :: a -> PointedList a -> PointedList a
    insert :: forall a. a -> PointedList a -> PointedList a
    insert = a -> PointedList a -> PointedList a
    forall a. a -> PointedList a -> PointedList a
    insertRight

    -- | Insert an element to the left of the focus, then move the focus to the new
    --   element.
    insertLeft :: a -> PointedList a -> PointedList a
    insertLeft :: forall a. a -> PointedList a -> PointedList a
    insertLeft a
    y (PointedList [a]
    ls a
    x [a]
    rs) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    y (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    rs)

    -- | Insert an element to the right of the focus, then move the focus to the
    --   new element.
    insertRight :: a -> PointedList a -> PointedList a
    insertRight :: forall a. a -> PointedList a -> PointedList a
    insertRight a
    y (PointedList [a]
    ls a
    x [a]
    rs) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    ls) a
    y [a]
    rs

    -- | An alias of 'deleteRight'.
    delete :: PointedList a -> Maybe (PointedList a)
    delete :: forall a. PointedList a -> Maybe (PointedList a)
    delete = PointedList a -> Maybe (PointedList a)
    forall a. PointedList a -> Maybe (PointedList a)
    deleteRight

    -- | Possibly delete the element at the focus, then move the element on the
    --   left to the focus. If no element is on the left, focus on the element to
    --   the right. If the deletion will cause the list to be empty, return
    --   'Nothing'.
    deleteLeft :: PointedList a -> Maybe (PointedList a)
    deleteLeft :: forall a. PointedList a -> Maybe (PointedList a)
    deleteLeft (PointedList [] a
    _ []    ) = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    deleteLeft (PointedList (a
    l:[a]
    ls) a
    _ [a]
    rs) = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    l [a]
    rs
    deleteLeft (PointedList [] a
    _ (a
    r:[a]
    rs)) = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [] a
    r [a]
    rs

    -- | Possibly delete the element at the focus, then move the element on the
    --   right to the focus. If no element is on the right, focus on the element to
    --   the left. If the deletion will cause the list to be empty, return
    --   'Nothing'.
    deleteRight :: PointedList a -> Maybe (PointedList a)
    deleteRight :: forall a. PointedList a -> Maybe (PointedList a)
    deleteRight (PointedList [] a
    _ []    ) = Maybe (PointedList a)
    forall a. Maybe a
    Nothing
    deleteRight (PointedList [a]
    ls a
    _ (a
    r:[a]
    rs)) = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    r [a]
    rs
    deleteRight (PointedList (a
    l:[a]
    ls) a
    _ []) = PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    ls a
    l []

    -- | Delete all elements in the list except the focus.
    deleteOthers :: PointedList a -> PointedList a
    deleteOthers :: forall a. PointedList a -> PointedList a
    deleteOthers (PointedList [a]
    _ a
    b [a]
    _) = [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [] a
    b []

    -- | The length of the list.
    length :: PointedList a -> Int
    length :: forall a. PointedList a -> Int
    length = (a -> Int -> Int) -> Int -> PointedList a -> Int
    forall a b. (a -> b -> b) -> b -> PointedList a -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ((Int -> Int) -> a -> Int -> Int
    forall a b. a -> b -> a
    const (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1)) Int
    0

    -- | Whether the focus is the first element.
    atStart :: PointedList a -> Bool
    atStart :: forall a. PointedList a -> Bool
    atStart (PointedList [] a
    _ [a]
    _) = Bool
    True
    atStart PointedList a
    _ = Bool
    False

    -- | Whether the focus is the last element.
    atEnd :: PointedList a -> Bool
    atEnd :: forall a. PointedList a -> Bool
    atEnd (PointedList [a]
    _ a
    _ []) = Bool
    True
    atEnd PointedList a
    _ = Bool
    False

    -- | Create a 'PointedList' of variations of the provided 'PointedList', in
    --   which each element is focused, with the provided 'PointedList' as the
    --   focus of the sets.
    positions :: PointedList a -> PointedList (PointedList a)
    positions :: forall a. PointedList a -> PointedList (PointedList a)
    positions p :: PointedList a
    p@(PointedList [a]
    ls a
    x [a]
    rs) = [PointedList a]
    -> PointedList a -> [PointedList a] -> PointedList (PointedList a)
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [PointedList a]
    left PointedList a
    p [PointedList a]
    right
      where left :: [PointedList a]
    left  = (PointedList a -> Maybe (PointedList a, PointedList a))
    -> PointedList a -> [PointedList a]
    forall b a. (b -> Maybe (a, b)) -> b -> [a]
    unfoldr (\PointedList a
    p -> (PointedList a -> (PointedList a, PointedList a))
    -> Maybe (PointedList a) -> Maybe (PointedList a, PointedList a)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((PointedList a -> PointedList a -> (PointedList a, PointedList a))
    -> PointedList a -> (PointedList a, PointedList a)
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (,)) (Maybe (PointedList a) -> Maybe (PointedList a, PointedList a))
    -> Maybe (PointedList a) -> Maybe (PointedList a, PointedList a)
    forall a b. (a -> b) -> a -> b
    $ PointedList a -> Maybe (PointedList a)
    forall a. PointedList a -> Maybe (PointedList a)
    previous PointedList a
    p) PointedList a
    p
            right :: [PointedList a]
    right = (PointedList a -> Maybe (PointedList a, PointedList a))
    -> PointedList a -> [PointedList a]
    forall b a. (b -> Maybe (a, b)) -> b -> [a]
    unfoldr (\PointedList a
    p -> (PointedList a -> (PointedList a, PointedList a))
    -> Maybe (PointedList a) -> Maybe (PointedList a, PointedList a)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((PointedList a -> PointedList a -> (PointedList a, PointedList a))
    -> PointedList a -> (PointedList a, PointedList a)
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (,)) (Maybe (PointedList a) -> Maybe (PointedList a, PointedList a))
    -> Maybe (PointedList a) -> Maybe (PointedList a, PointedList a)
    forall a b. (a -> b) -> a -> b
    $ PointedList a -> Maybe (PointedList a)
    forall a. PointedList a -> Maybe (PointedList a)
    next PointedList a
    p) PointedList a
    p

    -- | Map over the 'PointedList's created via 'positions', such that @f@ is
    --   called with each element of the list focused in the provided
    --   'PointedList'. An example makes this easier to understand:
    --
    -- > contextMap atStart (fromJust $ fromList [1..5])
    contextMap :: (PointedList a -> b) -> PointedList a -> PointedList b
    contextMap :: forall a b. (PointedList a -> b) -> PointedList a -> PointedList b
    contextMap PointedList a -> b
    f PointedList a
    z = (PointedList a -> b)
    -> PointedList (PointedList a) -> PointedList b
    forall a b. (a -> b) -> PointedList a -> PointedList b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap PointedList a -> b
    f (PointedList (PointedList a) -> PointedList b)
    -> PointedList (PointedList a) -> PointedList b
    forall a b. (a -> b) -> a -> b
    $ PointedList a -> PointedList (PointedList a)
    forall a. PointedList a -> PointedList (PointedList a)
    positions PointedList a
    z

    -- | Create a @'PointedList' a@ of @(a, 'Bool')@, in which the boolean values
    --   specify whether the current element has the focus. That is, all of the
    --   booleans will be 'False', except the focused element.
    withFocus :: PointedList a -> PointedList (a, Bool)
    withFocus :: forall a. PointedList a -> PointedList (a, Bool)
    withFocus (PointedList [a]
    a a
    b [a]
    c) =
        [(a, Bool)] -> (a, Bool) -> [(a, Bool)] -> PointedList (a, Bool)
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList ([a] -> [Bool] -> [(a, Bool)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    a (Bool -> [Bool]
    forall a. a -> [a]
    repeat Bool
    False)) (a
    b, Bool
    True) ([a] -> [Bool] -> [(a, Bool)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    c (Bool -> [Bool]
    forall a. a -> [a]
    repeat Bool
    False))

    -- | Move the focus to the specified index. The first element is at index 0.
    moveTo :: Int -> PointedList a -> Maybe (PointedList a)
    moveTo :: forall a. Int -> PointedList a -> Maybe (PointedList a)
    moveTo Int
    n PointedList a
    pl = Int -> PointedList a -> Maybe (PointedList a)
    forall a. Int -> PointedList a -> Maybe (PointedList a)
    moveN (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - (PointedList a -> Int
    forall a. PointedList a -> Int
    index PointedList a
    pl)) PointedList a
    pl

    -- | Move the focus by @n@, relative to the current index. Negative values move
    --   the focus backwards, positive values more forwards through the list.
    moveN :: Int -> PointedList a -> Maybe (PointedList a)
    moveN :: forall a. Int -> PointedList a -> Maybe (PointedList a)
    moveN Int
    n pl :: PointedList a
    pl@(PointedList [a]
    left a
    x [a]
    right) = Int -> [a] -> a -> [a] -> Maybe (PointedList a)
    forall {t} {a}.
    (Ord t, Num t) =>
    t -> [a] -> a -> [a] -> Maybe (PointedList a)
    go Int
    n [a]
    left a
    x [a]
    right
      where
      go :: t -> [a] -> a -> [a] -> Maybe (PointedList a)
    go t
    n [a]
    left a
    x [a]
    right = case t -> t -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare t
    n t
    0 of
       Ordering
    GT -> case [a]
    right of
         [] -> Maybe (PointedList a)
    forall a. Maybe a
    Nothing
         (a
    r:[a]
    rs) -> t -> [a] -> a -> [a] -> Maybe (PointedList a)
    go (t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    -t
    1) (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    left) a
    r [a]
    rs
       Ordering
    LT -> case [a]
    left of
         [] -> Maybe (PointedList a)
    forall a. Maybe a
    Nothing
         (a
    l:[a]
    ls) -> t -> [a] -> a -> [a] -> Maybe (PointedList a)
    go (t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    +t
    1) [a]
    ls a
    l (a
    xa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    right)
       Ordering
    EQ -> PointedList a -> Maybe (PointedList a)
    forall a. a -> Maybe a
    Just (PointedList a -> Maybe (PointedList a))
    -> PointedList a -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> a -> [a] -> PointedList a
    forall a. [a] -> a -> [a] -> PointedList a
    PointedList [a]
    left a
    x [a]
    right

    -- | Move the focus to the specified element, if it is present.
    --
    --   Patch with much faster algorithm provided by Runar Bjarnason for version
    --   0.3.2. Improved again by Runar Bjarnason for version 0.3.3 to support
    --   infinite lists on both sides of the focus.
    find :: Eq a => a -> PointedList a -> Maybe (PointedList a)
    find :: forall a. Eq a => a -> PointedList a -> Maybe (PointedList a)
    find a
    x PointedList a
    pl = (PointedList a -> Bool)
    -> PointedList (PointedList a) -> Maybe (PointedList a)
    forall {a}. (a -> Bool) -> PointedList a -> Maybe a
    find' ((a
    x a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) (a -> Bool) -> (PointedList a -> a) -> PointedList a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PointedList a -> a
    forall a. PointedList a -> a
    _focus) (PointedList (PointedList a) -> Maybe (PointedList a))
    -> PointedList (PointedList a) -> Maybe (PointedList a)
    forall a b. (a -> b) -> a -> b
    $ PointedList a -> PointedList (PointedList a)
    forall a. PointedList a -> PointedList (PointedList a)
    positions PointedList a
    pl
      where find' :: (a -> Bool) -> PointedList a -> Maybe a
    find' a -> Bool
    pred (PointedList [a]
    a a
    b [a]
    c) =
              if a -> Bool
    pred a
    b then a -> Maybe a
    forall a. a -> Maybe a
    Just a
    b
                        else (a -> Bool) -> [a] -> Maybe a
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    List.find a -> Bool
    pred ([a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    merge [a]
    a [a]
    c)
            merge :: [a] -> [a] -> [a]
    merge []     [a]
    ys = [a]
    ys
            merge (a
    x:[a]
    xs) [a]
    ys = a
    x a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : [a] -> [a] -> [a]
    merge [a]
    ys [a]
    xs

    -- | The index of the focus, leftmost is 0.
    index :: PointedList a -> Int
    index :: forall a. PointedList a -> Int
    index (PointedList [a]
    a a
    _ [a]
    _) = [a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    Prelude.length [a]
    a