{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}

{- |
Module      : Primus.NonEmpty
Description : utilities for nonempty lists
Copyright   : (c) Grant Weyburne, 2022
License     : BSD-3
-}
module Primus.NonEmpty (
  MLR (..),

  -- * zip
  zipWithExtras1,
  zipWithExtras,
  mlrOrdering,
  fromList1LR,

  -- * chunking
  chunksOf1,
  chunksRange1,
  chunkNLen,
  chunkNLen1,

  -- * split
  Split1 (..),
  split1Ordering,
  splitAt1,
  splitAt1',
  splitAt1GE,
  splitAts1,
  splits1,
  splits3,

  -- * partition
  partition1,
  --  toThese1,

  -- * span
  spanAdjacent1,
  breakAdjacent1,
  span1,
  break1,

  -- * ascending order methods
  Seq1 (..),
  isSequence1,
  isEnumAscending,
  seq1Ordering,

  -- * isomorphisms
  uncons1,
  unsnoc1,
  consNonEmpty,
  snocNonEmpty,

  -- * positive specific functions
  sumP,
  lengthP,

  -- * fold unfold
  foldMapM1,
  unfoldr1NE,
  unfoldrM1,

  -- * iterators
  iterateMaybe1,
  iterateMaybe1',
  iterateN1,
  replicateP,

  -- * miscellaneous
  appendL1,
  appendR1,
  snoc1,
  updateAt1,
  at1,
  setAt1,
  units1,
  unitsF,
  lengthExact1,
  take1,
  sum1,
  groupByAdjacent1,
  findDupsBy,
  replicate1,
  replicate1M,

  nonemptySnoc,
  nonempty,
  nonempty',
) where

import Control.Arrow
import Control.Monad
import Data.Either
import Data.Foldable
import Data.Function
import qualified Data.List as L
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as N
import Data.Pos
import Data.Semigroup
import Data.Semigroup.Foldable
import Data.These
import Data.Tuple
import qualified GHC.Exts as GE (IsList (..))
import Primus.Bool
import Primus.Error
import Primus.Fold
import Primus.Lens

-- | zips two nonempty lists together and puts any leftovers into 'MLR'
zipWithExtras1 :: (a -> b -> c) -> NonEmpty a -> NonEmpty b -> (NonEmpty c, MLR a b)
zipWithExtras1 :: (a -> b -> c) -> NonEmpty a -> NonEmpty b -> (NonEmpty c, MLR a b)
zipWithExtras1 a -> b -> c
f (a
a :| [a]
as) (b
b :| [b]
bs) = ([c] -> NonEmpty c) -> ([c], MLR a b) -> (NonEmpty c, MLR a b)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a -> b -> c
f a
a b
b c -> [c] -> NonEmpty c
forall a. a -> [a] -> NonEmpty a
:|) (([c], MLR a b) -> (NonEmpty c, MLR a b))
-> ([c], MLR a b) -> (NonEmpty c, MLR a b)
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> [a] -> [b] -> ([c], MLR a b)
forall a b c. (a -> b -> c) -> [a] -> [b] -> ([c], MLR a b)
zipWithExtras a -> b -> c
f [a]
as [b]
bs

-- | represents an optional 'Either' ie Maybe (Either (NonEmpty a) (NonEmpty b))
data MLR a b
  = -- | extra values on the left hand side
    MLRLeft !(NonEmpty a)
  | -- | both values have the same length
    MLREqual
  | -- | extra values on the right hand side
    MLRRight !(NonEmpty b)
  deriving stock (Int -> MLR a b -> ShowS
[MLR a b] -> ShowS
MLR a b -> String
(Int -> MLR a b -> ShowS)
-> (MLR a b -> String) -> ([MLR a b] -> ShowS) -> Show (MLR a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> MLR a b -> ShowS
forall a b. (Show a, Show b) => [MLR a b] -> ShowS
forall a b. (Show a, Show b) => MLR a b -> String
showList :: [MLR a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [MLR a b] -> ShowS
show :: MLR a b -> String
$cshow :: forall a b. (Show a, Show b) => MLR a b -> String
showsPrec :: Int -> MLR a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> MLR a b -> ShowS
Show, MLR a b -> MLR a b -> Bool
(MLR a b -> MLR a b -> Bool)
-> (MLR a b -> MLR a b -> Bool) -> Eq (MLR a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b. (Eq a, Eq b) => MLR a b -> MLR a b -> Bool
/= :: MLR a b -> MLR a b -> Bool
$c/= :: forall a b. (Eq a, Eq b) => MLR a b -> MLR a b -> Bool
== :: MLR a b -> MLR a b -> Bool
$c== :: forall a b. (Eq a, Eq b) => MLR a b -> MLR a b -> Bool
Eq, Eq (MLR a b)
Eq (MLR a b)
-> (MLR a b -> MLR a b -> Ordering)
-> (MLR a b -> MLR a b -> Bool)
-> (MLR a b -> MLR a b -> Bool)
-> (MLR a b -> MLR a b -> Bool)
-> (MLR a b -> MLR a b -> Bool)
-> (MLR a b -> MLR a b -> MLR a b)
-> (MLR a b -> MLR a b -> MLR a b)
-> Ord (MLR a b)
MLR a b -> MLR a b -> Bool
MLR a b -> MLR a b -> Ordering
MLR a b -> MLR a b -> MLR a b
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b. (Ord a, Ord b) => Eq (MLR a b)
forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Bool
forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Ordering
forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> MLR a b
min :: MLR a b -> MLR a b -> MLR a b
$cmin :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> MLR a b
max :: MLR a b -> MLR a b -> MLR a b
$cmax :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> MLR a b
>= :: MLR a b -> MLR a b -> Bool
$c>= :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Bool
> :: MLR a b -> MLR a b -> Bool
$c> :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Bool
<= :: MLR a b -> MLR a b -> Bool
$c<= :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Bool
< :: MLR a b -> MLR a b -> Bool
$c< :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Bool
compare :: MLR a b -> MLR a b -> Ordering
$ccompare :: forall a b. (Ord a, Ord b) => MLR a b -> MLR a b -> Ordering
$cp1Ord :: forall a b. (Ord a, Ord b) => Eq (MLR a b)
Ord)

-- | 'MLRLeft' predicate
mlrOrdering :: MLR a b -> Ordering
mlrOrdering :: MLR a b -> Ordering
mlrOrdering = \case
  MLRLeft{} -> Ordering
LT
  MLR a b
MLREqual -> Ordering
EQ
  MLRRight{} -> Ordering
GT

-- | zips two lists together and puts any leftovers into 'MLR'
zipWithExtras :: forall a b c. (a -> b -> c) -> [a] -> [b] -> ([c], MLR a b)
zipWithExtras :: (a -> b -> c) -> [a] -> [b] -> ([c], MLR a b)
zipWithExtras a -> b -> c
f = [a] -> [b] -> ([c], MLR a b)
go
 where
  go :: [a] -> [b] -> ([c], MLR a b)
go [] [] = ([], MLR a b
forall a b. MLR a b
MLREqual)
  go (a
a : [a]
as) (b
b : [b]
bs) = let ([c]
x, MLR a b
y) = [a] -> [b] -> ([c], MLR a b)
go [a]
as [b]
bs in (a -> b -> c
f a
a b
b c -> [c] -> [c]
forall a. a -> [a] -> [a]
: [c]
x, MLR a b
y)
  go (a
a : [a]
as) [] = ([], NonEmpty a -> MLR a b
forall a b. NonEmpty a -> MLR a b
MLRLeft (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as))
  go [] (b
b : [b]
bs) = ([], NonEmpty b -> MLR a b
forall a b. NonEmpty b -> MLR a b
MLRRight (b
b b -> [b] -> NonEmpty b
forall a. a -> [a] -> NonEmpty a
:| [b]
bs))

-- | conversion from list to a nonempty list
fromList1LR :: [a] -> Either String (NonEmpty a)
fromList1LR :: [a] -> Either String (NonEmpty a)
fromList1LR =
  \case
    [] -> String -> Either String (NonEmpty a)
forall a b. a -> Either a b
Left String
"fromList1LR: empty list"
    a
n : [a]
ns -> NonEmpty a -> Either String (NonEmpty a)
forall a b. b -> Either a b
Right (NonEmpty a -> Either String (NonEmpty a))
-> NonEmpty a -> Either String (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ a
n a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
ns

-- | split a nonempty list into a nonempty list of nonempty chunks
chunksOf1 :: Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
chunksOf1 :: Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
chunksOf1 = (Pos -> Pos -> NonEmpty a -> NonEmpty (NonEmpty a))
-> Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join Pos -> Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
forall a. Pos -> Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
chunksRange1

{- | split a nonempty list into a nonempty list of nonempty chunks given a chunk size and how many to skip each iteration
 can decide the size of the chunks and how many elements to skip
-}
chunksRange1 :: Pos -> Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
chunksRange1 :: Pos -> Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
chunksRange1 Pos
n (Pos Int
skip) = (NonEmpty a -> (NonEmpty a, [a]))
-> NonEmpty a -> NonEmpty (NonEmpty a)
forall s a. (NonEmpty s -> (a, [s])) -> NonEmpty s -> NonEmpty a
unfoldr1NE (Pos -> NonEmpty a -> NonEmpty a
forall a. Pos -> NonEmpty a -> NonEmpty a
take1 Pos
n (NonEmpty a -> NonEmpty a)
-> (NonEmpty a -> [a]) -> NonEmpty a -> (NonEmpty a, [a])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Int -> NonEmpty a -> [a]
forall a. Int -> NonEmpty a -> [a]
N.drop Int
skip)

{- | creates a nonempty container of length "sz" with chunks of a given size: see 'chunkNLen'
 must fill the container exactly
-}
chunkNLen1 ::
  forall a u.
  Foldable u =>
  Pos ->
  Pos ->
  u a ->
  Either String (NonEmpty (NonEmpty a))
chunkNLen1 :: Pos -> Pos -> u a -> Either String (NonEmpty (NonEmpty a))
chunkNLen1 Pos
sz = NonEmpty () -> Pos -> u a -> Either String (NonEmpty (NonEmpty a))
forall (t :: * -> *) a (u :: * -> *) z.
(Traversable t, Foldable u) =>
t z -> Pos -> u a -> Either String (t (NonEmpty a))
chunkNLen (Pos -> NonEmpty ()
units1 Pos
sz)

{- | fills a container "tz" with chunks of size "len"
 must fill the container exactly
-}
chunkNLen ::
  forall t a u z.
  (Traversable t, Foldable u) =>
  t z ->
  Pos ->
  u a ->
  Either String (t (NonEmpty a))
chunkNLen :: t z -> Pos -> u a -> Either String (t (NonEmpty a))
chunkNLen t z
tz Pos
len u a
ua = do
  ([a] -> Either String ([a], NonEmpty a))
-> t z -> [a] -> Either String (t (NonEmpty a))
forall (t :: * -> *) a (u :: * -> *) b z.
(Traversable t, Foldable u) =>
(u a -> Either String (u a, b))
-> t z -> u a -> Either String (t b)
chunkN' [a] -> Either String ([a], NonEmpty a)
f t z
tz (u a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList u a
ua)
 where
  f :: [a] -> Either String ([a], NonEmpty a)
  f :: [a] -> Either String ([a], NonEmpty a)
f = \case
    [] -> String -> Either String ([a], NonEmpty a)
forall a b. a -> Either a b
Left String
"chunkNLen: not enough data"
    a
x : [a]
xs -> (NonEmpty a, [a]) -> ([a], NonEmpty a)
forall a b. (a, b) -> (b, a)
swap ((NonEmpty a, [a]) -> ([a], NonEmpty a))
-> Either String (NonEmpty a, [a])
-> Either String ([a], NonEmpty a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pos -> NonEmpty a -> Either String (NonEmpty a, [a])
forall a. Pos -> NonEmpty a -> Either String (NonEmpty a, [a])
splitAt1GE Pos
len (a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs)

{- | unfoldr for a nonempty list

will not terminate if the user keeps returning a larger [s] than received
-}
unfoldr1NE ::
  forall s a.
  (NonEmpty s -> (a, [s])) ->
  NonEmpty s ->
  NonEmpty a
unfoldr1NE :: (NonEmpty s -> (a, [s])) -> NonEmpty s -> NonEmpty a
unfoldr1NE NonEmpty s -> (a, [s])
f = NonEmpty s -> NonEmpty a
go
 where
  go :: NonEmpty s -> NonEmpty a
  go :: NonEmpty s -> NonEmpty a
go NonEmpty s
ns =
    let (a
a, [s]
ys) = NonEmpty s -> (a, [s])
f NonEmpty s
ns
     in (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|) ([a] -> NonEmpty a) -> [a] -> NonEmpty a
forall a b. (a -> b) -> a -> b
$ case [s]
ys of
          [] -> []
          s
x : [s]
xs -> NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
N.toList (NonEmpty s -> NonEmpty a
go (s
x s -> [s] -> NonEmpty s
forall a. a -> [a] -> NonEmpty a
:| [s]
xs))

-- | 'replicate' for a nonempty list
replicate1 :: Pos -> a -> NonEmpty a
replicate1 :: Pos -> a -> NonEmpty a
replicate1 (Pos Int
n) a
a = a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
a

-- | 'replicateM' for a nonempty list
replicate1M :: Applicative m => Pos -> m a -> m (NonEmpty a)
replicate1M :: Pos -> m a -> m (NonEmpty a)
replicate1M (Pos Int
n) m a
ma = a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
(:|) (a -> [a] -> NonEmpty a) -> m a -> m ([a] -> NonEmpty a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
ma m ([a] -> NonEmpty a) -> m [a] -> m (NonEmpty a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m a -> m [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) m a
ma

-- | 'partitionThese' for a nonempty list
partition1 ::
  Foldable1 t =>
  (a -> Bool) ->
  t a ->
  These (NonEmpty a) (NonEmpty a)
partition1 :: (a -> Bool) -> t a -> These (NonEmpty a) (NonEmpty a)
partition1 a -> Bool
p =
  NonEmpty (These (NonEmpty a) (NonEmpty a))
-> These (NonEmpty a) (NonEmpty a)
forall a. Semigroup a => NonEmpty a -> a
sconcat
    (NonEmpty (These (NonEmpty a) (NonEmpty a))
 -> These (NonEmpty a) (NonEmpty a))
-> (t a -> NonEmpty (These (NonEmpty a) (NonEmpty a)))
-> t a
-> These (NonEmpty a) (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> These (NonEmpty a) (NonEmpty a))
-> NonEmpty a -> NonEmpty (These (NonEmpty a) (NonEmpty a))
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
N.map ((a -> Bool)
-> (a -> These (NonEmpty a) (NonEmpty a))
-> (a -> These (NonEmpty a) (NonEmpty a))
-> a
-> These (NonEmpty a) (NonEmpty a)
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
boolM a -> Bool
p (NonEmpty a -> These (NonEmpty a) (NonEmpty a)
forall a b. a -> These a b
This (NonEmpty a -> These (NonEmpty a) (NonEmpty a))
-> (a -> NonEmpty a) -> a -> These (NonEmpty a) (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) (NonEmpty a -> These (NonEmpty a) (NonEmpty a)
forall a b. b -> These a b
That (NonEmpty a -> These (NonEmpty a) (NonEmpty a))
-> (a -> NonEmpty a) -> a -> These (NonEmpty a) (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure))
    (NonEmpty a -> NonEmpty (These (NonEmpty a) (NonEmpty a)))
-> (t a -> NonEmpty a)
-> t a
-> NonEmpty (These (NonEmpty a) (NonEmpty a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty

-- | internal function used by 'span1'
toThese1 ::
  These (NonEmpty a) (NonEmpty b) ->
  ([a], [b]) ->
  These (NonEmpty a) (NonEmpty b)
toThese1 :: These (NonEmpty a) (NonEmpty b)
-> ([a], [b]) -> These (NonEmpty a) (NonEmpty b)
toThese1 These (NonEmpty a) (NonEmpty b)
th ([a], [b])
ns =
  These (NonEmpty a) (NonEmpty b)
th These (NonEmpty a) (NonEmpty b)
-> (These (NonEmpty a) (NonEmpty b)
    -> These (NonEmpty a) (NonEmpty b))
-> These (NonEmpty a) (NonEmpty b)
forall a b. a -> (a -> b) -> b
& case ([a], [b])
ns of
    ([], []) -> These (NonEmpty a) (NonEmpty b) -> These (NonEmpty a) (NonEmpty b)
forall a. a -> a
id
    (a
a : [a]
as, []) -> (These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
forall a. Semigroup a => a -> a -> a
<> NonEmpty a -> These (NonEmpty a) (NonEmpty b)
forall a b. a -> These a b
This (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as))
    ([], b
b : [b]
bs) -> (These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
forall a. Semigroup a => a -> a -> a
<> NonEmpty b -> These (NonEmpty a) (NonEmpty b)
forall a b. b -> These a b
That (b
b b -> [b] -> NonEmpty b
forall a. a -> [a] -> NonEmpty a
:| [b]
bs))
    (a
a : [a]
as, b
b : [b]
bs) -> (These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
-> These (NonEmpty a) (NonEmpty b)
forall a. Semigroup a => a -> a -> a
<> NonEmpty a -> NonEmpty b -> These (NonEmpty a) (NonEmpty b)
forall a b. a -> b -> These a b
These (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as) (b
b b -> [b] -> NonEmpty b
forall a. a -> [a] -> NonEmpty a
:| [b]
bs))

-- | 'span' for a nonempty list
span1 ::
  Foldable1 t =>
  (a -> Bool) ->
  t a ->
  These (NonEmpty a) (NonEmpty a)
span1 :: (a -> Bool) -> t a -> These (NonEmpty a) (NonEmpty a)
span1 a -> Bool
p (t a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty -> (a
a :| [a]
as)) =
  These (NonEmpty a) (NonEmpty a)
-> ([a], [a]) -> These (NonEmpty a) (NonEmpty a)
forall a b.
These (NonEmpty a) (NonEmpty b)
-> ([a], [b]) -> These (NonEmpty a) (NonEmpty b)
toThese1
    ( (a -> Bool)
-> (a -> These (NonEmpty a) (NonEmpty a))
-> (a -> These (NonEmpty a) (NonEmpty a))
-> a
-> These (NonEmpty a) (NonEmpty a)
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
boolM
        a -> Bool
p
        (NonEmpty a -> These (NonEmpty a) (NonEmpty a)
forall a b. b -> These a b
That (NonEmpty a -> These (NonEmpty a) (NonEmpty a))
-> (a -> NonEmpty a) -> a -> These (NonEmpty a) (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
        (NonEmpty a -> These (NonEmpty a) (NonEmpty a)
forall a b. a -> These a b
This (NonEmpty a -> These (NonEmpty a) (NonEmpty a))
-> (a -> NonEmpty a) -> a -> These (NonEmpty a) (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
        a
a
    )
    ((a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
L.span a -> Bool
p [a]
as)

-- | 'break' for a nonempty list
break1 ::
  Foldable1 t =>
  (a -> Bool) ->
  t a ->
  These (NonEmpty a) (NonEmpty a)
break1 :: (a -> Bool) -> t a -> These (NonEmpty a) (NonEmpty a)
break1 a -> Bool
p = (a -> Bool) -> t a -> These (NonEmpty a) (NonEmpty a)
forall (t :: * -> *) a.
Foldable1 t =>
(a -> Bool) -> t a -> These (NonEmpty a) (NonEmpty a)
span1 (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p)

-- | 'sum' for a nonempty list
sum1 :: (Foldable1 t, Num a) => t a -> a
sum1 :: t a -> a
sum1 = (a -> a -> a) -> a -> t a -> a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' a -> a -> a
forall a. Num a => a -> a -> a
(+) a
0

-- | predicate for an ascending nonempty list
isSequence1 :: (Foldable1 t, Eq a, Enum a) => t a -> Bool
isSequence1 :: t a -> Bool
isSequence1 = (Ordering
EQ Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
==) (Ordering -> Bool) -> (t a -> Ordering) -> t a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq1 a -> Ordering
forall a. Seq1 a -> Ordering
seq1Ordering (Seq1 a -> Ordering) -> (t a -> Seq1 a) -> t a -> Ordering
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t a -> Seq1 a
forall (t :: * -> *) a.
(Foldable1 t, Eq a, Enum a) =>
t a -> Seq1 a
isEnumAscending

-- | possible results for determining if a nonempty list is in ascending order
data Seq1 a
  = -- | generated enumerable sequence is shorter than the original list
    S1Short !(NonEmpty a)
  | -- | first mismatch
    S1Fail !(a, a)
  | -- | both sequences match
    S1Ok
  deriving stock (Int -> Seq1 a -> ShowS
[Seq1 a] -> ShowS
Seq1 a -> String
(Int -> Seq1 a -> ShowS)
-> (Seq1 a -> String) -> ([Seq1 a] -> ShowS) -> Show (Seq1 a)
forall a. Show a => Int -> Seq1 a -> ShowS
forall a. Show a => [Seq1 a] -> ShowS
forall a. Show a => Seq1 a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Seq1 a] -> ShowS
$cshowList :: forall a. Show a => [Seq1 a] -> ShowS
show :: Seq1 a -> String
$cshow :: forall a. Show a => Seq1 a -> String
showsPrec :: Int -> Seq1 a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Seq1 a -> ShowS
Show, Seq1 a -> Seq1 a -> Bool
(Seq1 a -> Seq1 a -> Bool)
-> (Seq1 a -> Seq1 a -> Bool) -> Eq (Seq1 a)
forall a. Eq a => Seq1 a -> Seq1 a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Seq1 a -> Seq1 a -> Bool
$c/= :: forall a. Eq a => Seq1 a -> Seq1 a -> Bool
== :: Seq1 a -> Seq1 a -> Bool
$c== :: forall a. Eq a => Seq1 a -> Seq1 a -> Bool
Eq, Eq (Seq1 a)
Eq (Seq1 a)
-> (Seq1 a -> Seq1 a -> Ordering)
-> (Seq1 a -> Seq1 a -> Bool)
-> (Seq1 a -> Seq1 a -> Bool)
-> (Seq1 a -> Seq1 a -> Bool)
-> (Seq1 a -> Seq1 a -> Bool)
-> (Seq1 a -> Seq1 a -> Seq1 a)
-> (Seq1 a -> Seq1 a -> Seq1 a)
-> Ord (Seq1 a)
Seq1 a -> Seq1 a -> Bool
Seq1 a -> Seq1 a -> Ordering
Seq1 a -> Seq1 a -> Seq1 a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Seq1 a)
forall a. Ord a => Seq1 a -> Seq1 a -> Bool
forall a. Ord a => Seq1 a -> Seq1 a -> Ordering
forall a. Ord a => Seq1 a -> Seq1 a -> Seq1 a
min :: Seq1 a -> Seq1 a -> Seq1 a
$cmin :: forall a. Ord a => Seq1 a -> Seq1 a -> Seq1 a
max :: Seq1 a -> Seq1 a -> Seq1 a
$cmax :: forall a. Ord a => Seq1 a -> Seq1 a -> Seq1 a
>= :: Seq1 a -> Seq1 a -> Bool
$c>= :: forall a. Ord a => Seq1 a -> Seq1 a -> Bool
> :: Seq1 a -> Seq1 a -> Bool
$c> :: forall a. Ord a => Seq1 a -> Seq1 a -> Bool
<= :: Seq1 a -> Seq1 a -> Bool
$c<= :: forall a. Ord a => Seq1 a -> Seq1 a -> Bool
< :: Seq1 a -> Seq1 a -> Bool
$c< :: forall a. Ord a => Seq1 a -> Seq1 a -> Bool
compare :: Seq1 a -> Seq1 a -> Ordering
$ccompare :: forall a. Ord a => Seq1 a -> Seq1 a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Seq1 a)
Ord, a -> Seq1 b -> Seq1 a
(a -> b) -> Seq1 a -> Seq1 b
(forall a b. (a -> b) -> Seq1 a -> Seq1 b)
-> (forall a b. a -> Seq1 b -> Seq1 a) -> Functor Seq1
forall a b. a -> Seq1 b -> Seq1 a
forall a b. (a -> b) -> Seq1 a -> Seq1 b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Seq1 b -> Seq1 a
$c<$ :: forall a b. a -> Seq1 b -> Seq1 a
fmap :: (a -> b) -> Seq1 a -> Seq1 b
$cfmap :: forall a b. (a -> b) -> Seq1 a -> Seq1 b
Functor)

-- | predicate for 'S1Short'
seq1Ordering :: Seq1 a -> Ordering
seq1Ordering :: Seq1 a -> Ordering
seq1Ordering = \case
  S1Short{} -> Ordering
LT
  S1Ok{} -> Ordering
EQ
  S1Fail{} -> Ordering
GT

-- | shows the first failure or if the length of the enum is too short
isEnumAscending :: forall t a. (Foldable1 t, Eq a, Enum a) => t a -> Seq1 a
isEnumAscending :: t a -> Seq1 a
isEnumAscending (t a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty -> as :: NonEmpty a
as@(a
a :| [a]
_)) =
  let (NonEmpty (Either (a, a) ())
cs, MLR a a
me) = (a -> a -> Either (a, a) ())
-> NonEmpty a
-> NonEmpty a
-> (NonEmpty (Either (a, a) ()), MLR a a)
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> (NonEmpty c, MLR a b)
zipWithExtras1 a -> a -> Either (a, a) ()
f (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
1 [a
a ..]) NonEmpty a
as
   in case MLR a a
me of
        MLRLeft NonEmpty a
_ -> ((a, a) -> Seq1 a)
-> (NonEmpty () -> Seq1 a) -> Either (a, a) (NonEmpty ()) -> Seq1 a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (a, a) -> Seq1 a
forall a. (a, a) -> Seq1 a
S1Fail (Seq1 a -> NonEmpty () -> Seq1 a
forall a b. a -> b -> a
const Seq1 a
forall a. Seq1 a
S1Ok) (Either (a, a) (NonEmpty ()) -> Seq1 a)
-> Either (a, a) (NonEmpty ()) -> Seq1 a
forall a b. (a -> b) -> a -> b
$ NonEmpty (Either (a, a) ()) -> Either (a, a) (NonEmpty ())
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA NonEmpty (Either (a, a) ())
cs
        MLR a a
MLREqual -> ((a, a) -> Seq1 a)
-> (NonEmpty () -> Seq1 a) -> Either (a, a) (NonEmpty ()) -> Seq1 a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (a, a) -> Seq1 a
forall a. (a, a) -> Seq1 a
S1Fail (Seq1 a -> NonEmpty () -> Seq1 a
forall a b. a -> b -> a
const Seq1 a
forall a. Seq1 a
S1Ok) (Either (a, a) (NonEmpty ()) -> Seq1 a)
-> Either (a, a) (NonEmpty ()) -> Seq1 a
forall a b. (a -> b) -> a -> b
$ NonEmpty (Either (a, a) ()) -> Either (a, a) (NonEmpty ())
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA NonEmpty (Either (a, a) ())
cs
        MLRRight NonEmpty a
zs -> NonEmpty a -> Seq1 a
forall a. NonEmpty a -> Seq1 a
S1Short NonEmpty a
zs
 where
  f :: a -> a -> Either (a, a) ()
  f :: a -> a -> Either (a, a) ()
f a
x a
y = if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y then () -> Either (a, a) ()
forall a b. b -> Either a b
Right () else (a, a) -> Either (a, a) ()
forall a b. a -> Either a b
Left (a
x, a
y)

-- | snoc for a nonempty list
snoc1 :: Foldable t => t a -> a -> NonEmpty a
snoc1 :: t a -> a -> NonEmpty a
snoc1 t a
as a
a = (a -> NonEmpty a -> NonEmpty a) -> NonEmpty a -> t a -> NonEmpty a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> NonEmpty a -> NonEmpty a
forall a. a -> NonEmpty a -> NonEmpty a
(N.<|) (a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) t a
as

-- | unsnoc for a nonempty list
unsnoc1 :: forall a. NonEmpty a -> ([a], a)
unsnoc1 :: NonEmpty a -> ([a], a)
unsnoc1 = (a -> [a] -> ([a], a)) -> (a, [a]) -> ([a], a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> [a] -> ([a], a)
go ((a, [a]) -> ([a], a))
-> (NonEmpty a -> (a, [a])) -> NonEmpty a -> ([a], a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> (a, [a])
forall a. NonEmpty a -> (a, [a])
uncons1
 where
  go :: a -> [a] -> ([a], a)
  go :: a -> [a] -> ([a], a)
go a
n [] = ([], a
n)
  go a
n (a
x : [a]
xs) = ([a] -> [a]) -> ([a], a) -> ([a], a)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
n a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (a -> [a] -> ([a], a)
go a
x [a]
xs)

nonempty :: (a -> [a] -> b) -> NonEmpty a -> b
nonempty :: (a -> [a] -> b) -> NonEmpty a -> b
nonempty a -> [a] -> b
f (a
a:|[a]
as) = a -> [a] -> b
f a
a [a]
as

nonempty' :: NonEmpty a -> (a -> [a] -> b) -> b
nonempty' :: NonEmpty a -> (a -> [a] -> b) -> b
nonempty' = ((a -> [a] -> b) -> NonEmpty a -> b)
-> NonEmpty a -> (a -> [a] -> b) -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> [a] -> b) -> NonEmpty a -> b
forall a b. (a -> [a] -> b) -> NonEmpty a -> b
nonempty

nonemptySnoc :: ([a] -> a -> b) -> NonEmpty a -> b
nonemptySnoc :: ([a] -> a -> b) -> NonEmpty a -> b
nonemptySnoc [a] -> a -> b
f = ([a] -> a -> b) -> ([a], a) -> b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [a] -> a -> b
f (([a], a) -> b) -> (NonEmpty a -> ([a], a)) -> NonEmpty a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> ([a], a)
forall a. NonEmpty a -> ([a], a)
unsnoc1

-- | uncons for a nonempty list
uncons1 :: forall a. NonEmpty a -> (a, [a])
uncons1 :: NonEmpty a -> (a, [a])
uncons1 (a
z :| [a]
zs) = (a
z, [a]
zs)

-- | cons iso from 'NonEmpty'
consNonEmpty :: Iso (NonEmpty a) (NonEmpty b) (a, [a]) (b, [b])
consNonEmpty :: p (a, [a]) (f (b, [b])) -> p (NonEmpty a) (f (NonEmpty b))
consNonEmpty = (NonEmpty a -> (a, [a]))
-> ((b, [b]) -> NonEmpty b)
-> Iso (NonEmpty a) (NonEmpty b) (a, [a]) (b, [b])
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso NonEmpty a -> (a, [a])
forall a. NonEmpty a -> (a, [a])
uncons1 ((b -> [b] -> NonEmpty b) -> (b, [b]) -> NonEmpty b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry b -> [b] -> NonEmpty b
forall a. a -> [a] -> NonEmpty a
(:|))

-- | snoc iso from 'NonEmpty'
snocNonEmpty :: Iso (NonEmpty a) (NonEmpty b) ([a], a) ([b], b)
snocNonEmpty :: p ([a], a) (f ([b], b)) -> p (NonEmpty a) (f (NonEmpty b))
snocNonEmpty = (NonEmpty a -> ([a], a))
-> (([b], b) -> NonEmpty b)
-> Iso (NonEmpty a) (NonEmpty b) ([a], a) ([b], b)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso NonEmpty a -> ([a], a)
forall a. NonEmpty a -> ([a], a)
unsnoc1 (([b] -> b -> NonEmpty b) -> ([b], b) -> NonEmpty b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [b] -> b -> NonEmpty b
forall (t :: * -> *) a. Foldable t => t a -> a -> NonEmpty a
snoc1)

-- | 'N.groupBy1' but applies the predicate to adjacent elements
groupByAdjacent1 :: forall a. (a -> a -> Bool) -> NonEmpty a -> NonEmpty (NonEmpty a)
groupByAdjacent1 :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty (NonEmpty a)
groupByAdjacent1 a -> a -> Bool
p (a
a0 :| [a]
as0) =
  let ([a]
as, [NonEmpty a]
ass) = a -> [a] -> ([a], [NonEmpty a])
go a
a0 [a]
as0
   in (a
a0 a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as) NonEmpty a -> [NonEmpty a] -> NonEmpty (NonEmpty a)
forall a. a -> [a] -> NonEmpty a
:| [NonEmpty a]
ass
 where
  go :: a -> [a] -> ([a], [NonEmpty a])
  go :: a -> [a] -> ([a], [NonEmpty a])
go a
a' = \case
    [] -> ([], [])
    a
a : [a]
as ->
      let ([a]
ys, [NonEmpty a]
zs) = a -> [a] -> ([a], [NonEmpty a])
go a
a [a]
as
       in if a -> a -> Bool
p a
a' a
a
            then (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ys, [NonEmpty a]
zs)
            else ([], (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
ys) NonEmpty a -> [NonEmpty a] -> [NonEmpty a]
forall a. a -> [a] -> [a]
: [NonEmpty a]
zs)

-- | partition duplicates elements together with their positiion
findDupsBy :: forall a c. Ord c => (a -> c) -> [a] -> ([NonEmpty (Int, a)], [(Int, a)])
findDupsBy :: (a -> c) -> [a] -> ([NonEmpty (Int, a)], [(Int, a)])
findDupsBy a -> c
f =
  [Either (NonEmpty (Int, a)) (Int, a)]
-> ([NonEmpty (Int, a)], [(Int, a)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers
    ([Either (NonEmpty (Int, a)) (Int, a)]
 -> ([NonEmpty (Int, a)], [(Int, a)]))
-> ([a] -> [Either (NonEmpty (Int, a)) (Int, a)])
-> [a]
-> ([NonEmpty (Int, a)], [(Int, a)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty (Int, a) -> Either (NonEmpty (Int, a)) (Int, a))
-> [NonEmpty (Int, a)] -> [Either (NonEmpty (Int, a)) (Int, a)]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty (Int, a) -> Either (NonEmpty (Int, a)) (Int, a)
g
    ([NonEmpty (Int, a)] -> [Either (NonEmpty (Int, a)) (Int, a)])
-> ([a] -> [NonEmpty (Int, a)])
-> [a]
-> [Either (NonEmpty (Int, a)) (Int, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, a) -> c) -> [(Int, a)] -> [NonEmpty (Int, a)]
forall b a. Ord b => (a -> b) -> [a] -> [NonEmpty a]
N.groupAllWith (a -> c
f (a -> c) -> ((Int, a) -> a) -> (Int, a) -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, a) -> a
forall a b. (a, b) -> b
snd)
    ([(Int, a)] -> [NonEmpty (Int, a)])
-> ([a] -> [(Int, a)]) -> [a] -> [NonEmpty (Int, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..]
 where
  g :: NonEmpty (Int, a) -> Either (NonEmpty (Int, a)) (Int, a)
  g :: NonEmpty (Int, a) -> Either (NonEmpty (Int, a)) (Int, a)
g = \case
    (Int, a)
x :| [] -> (Int, a) -> Either (NonEmpty (Int, a)) (Int, a)
forall a b. b -> Either a b
Right (Int, a)
x
    (Int, a)
x :| (Int, a)
y : [(Int, a)]
ys -> NonEmpty (Int, a) -> Either (NonEmpty (Int, a)) (Int, a)
forall a b. a -> Either a b
Left ((Int, a)
x (Int, a) -> [(Int, a)] -> NonEmpty (Int, a)
forall a. a -> [a] -> NonEmpty a
:| (Int, a)
y (Int, a) -> [(Int, a)] -> [(Int, a)]
forall a. a -> [a] -> [a]
: [(Int, a)]
ys)

-- | "foldMapM" for nonempty containers: uses Semigroup instead of Monoid
foldMapM1 ::
  forall b m f a.
  (Semigroup b, Monad m, Foldable1 f) =>
  (a -> m b) ->
  f a ->
  m b
foldMapM1 :: (a -> m b) -> f a -> m b
foldMapM1 a -> m b
f (f a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty -> a
n :| [a]
ns) = (a -> (b -> m b) -> b -> m b) -> (b -> m b) -> [a] -> b -> m b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> (b -> m b) -> b -> m b
step b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return [a]
ns (b -> m b) -> m b -> m b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> m b
f a
n
 where
  step :: a -> (b -> m b) -> b -> m b
  step :: a -> (b -> m b) -> b -> m b
step a
x b -> m b
r b
z = a -> m b
f a
x m b -> (b -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \b
y -> b -> m b
r (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! b
z b -> b -> b
forall a. Semigroup a => a -> a -> a
<> b
y

-- | 'Primus.Fold.unfoldM' for nonempty results
unfoldrM1 :: Monad m => (s -> m (a, Maybe s)) -> s -> m (NonEmpty a)
unfoldrM1 :: (s -> m (a, Maybe s)) -> s -> m (NonEmpty a)
unfoldrM1 s -> m (a, Maybe s)
f s
s = do
  (a
a, Maybe s
ms) <- s -> m (a, Maybe s)
f s
s
  case Maybe s
ms of
    Maybe s
Nothing -> NonEmpty a -> m (NonEmpty a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [])
    Just s
s' -> (a
a a -> NonEmpty a -> NonEmpty a
forall a. a -> NonEmpty a -> NonEmpty a
N.<|) (NonEmpty a -> NonEmpty a) -> m (NonEmpty a) -> m (NonEmpty a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (s -> m (a, Maybe s)) -> s -> m (NonEmpty a)
forall (m :: * -> *) s a.
Monad m =>
(s -> m (a, Maybe s)) -> s -> m (NonEmpty a)
unfoldrM1 s -> m (a, Maybe s)
f s
s'

-- | 'take' for a nonempty list
take1 :: Pos -> NonEmpty a -> NonEmpty a
take1 :: Pos -> NonEmpty a -> NonEmpty a
take1 (Pos Int
i) (a
a :| [a]
as) = a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [a]
as

-- | 'splitAt' for a nonempty list but doesnt guarantee the number of elements
splitAt1 :: Pos -> NonEmpty a -> (NonEmpty a, [a])
splitAt1 :: Pos -> NonEmpty a -> (NonEmpty a, [a])
splitAt1 (Pos Int
i) (a
a :| [a]
as) = ([a] -> NonEmpty a) -> ([a], [a]) -> (NonEmpty a, [a])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|) (Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [a]
as)

-- | comparator for 'Split1'
split1Ordering :: Split1 a -> Ordering
split1Ordering :: Split1 a -> Ordering
split1Ordering = \case
  SplitLT{} -> Ordering
LT
  SplitEQ{} -> Ordering
EQ
  SplitGT{} -> Ordering
GT

-- | represents the status of a split a nonempty list
data Split1 a
  = SplitLT !Pos
  | SplitEQ
  | SplitGT !(NonEmpty a)
  deriving stock (Eq (Split1 a)
Eq (Split1 a)
-> (Split1 a -> Split1 a -> Ordering)
-> (Split1 a -> Split1 a -> Bool)
-> (Split1 a -> Split1 a -> Bool)
-> (Split1 a -> Split1 a -> Bool)
-> (Split1 a -> Split1 a -> Bool)
-> (Split1 a -> Split1 a -> Split1 a)
-> (Split1 a -> Split1 a -> Split1 a)
-> Ord (Split1 a)
Split1 a -> Split1 a -> Bool
Split1 a -> Split1 a -> Ordering
Split1 a -> Split1 a -> Split1 a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Split1 a)
forall a. Ord a => Split1 a -> Split1 a -> Bool
forall a. Ord a => Split1 a -> Split1 a -> Ordering
forall a. Ord a => Split1 a -> Split1 a -> Split1 a
min :: Split1 a -> Split1 a -> Split1 a
$cmin :: forall a. Ord a => Split1 a -> Split1 a -> Split1 a
max :: Split1 a -> Split1 a -> Split1 a
$cmax :: forall a. Ord a => Split1 a -> Split1 a -> Split1 a
>= :: Split1 a -> Split1 a -> Bool
$c>= :: forall a. Ord a => Split1 a -> Split1 a -> Bool
> :: Split1 a -> Split1 a -> Bool
$c> :: forall a. Ord a => Split1 a -> Split1 a -> Bool
<= :: Split1 a -> Split1 a -> Bool
$c<= :: forall a. Ord a => Split1 a -> Split1 a -> Bool
< :: Split1 a -> Split1 a -> Bool
$c< :: forall a. Ord a => Split1 a -> Split1 a -> Bool
compare :: Split1 a -> Split1 a -> Ordering
$ccompare :: forall a. Ord a => Split1 a -> Split1 a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Split1 a)
Ord, Int -> Split1 a -> ShowS
[Split1 a] -> ShowS
Split1 a -> String
(Int -> Split1 a -> ShowS)
-> (Split1 a -> String) -> ([Split1 a] -> ShowS) -> Show (Split1 a)
forall a. Show a => Int -> Split1 a -> ShowS
forall a. Show a => [Split1 a] -> ShowS
forall a. Show a => Split1 a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Split1 a] -> ShowS
$cshowList :: forall a. Show a => [Split1 a] -> ShowS
show :: Split1 a -> String
$cshow :: forall a. Show a => Split1 a -> String
showsPrec :: Int -> Split1 a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Split1 a -> ShowS
Show, Split1 a -> Split1 a -> Bool
(Split1 a -> Split1 a -> Bool)
-> (Split1 a -> Split1 a -> Bool) -> Eq (Split1 a)
forall a. Eq a => Split1 a -> Split1 a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Split1 a -> Split1 a -> Bool
$c/= :: forall a. Eq a => Split1 a -> Split1 a -> Bool
== :: Split1 a -> Split1 a -> Bool
$c== :: forall a. Eq a => Split1 a -> Split1 a -> Bool
Eq)

-- | split a nonempty list preserving information about the split
splitAt1' :: forall a. Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
splitAt1' :: Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
splitAt1' = Pos -> Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
go Pos
_1P
 where
  go :: Pos -> Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
  go :: Pos -> Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
go !Pos
i !Pos
n (a
a :| [])
    | Pos
i Pos -> Pos -> Bool
forall a. Eq a => a -> a -> Bool
== Pos
n = (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [], Split1 a
forall a. Split1 a
SplitEQ)
    | Bool
otherwise = (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [], Pos -> Split1 a
forall a. Pos -> Split1 a
SplitLT Pos
i)
  go !Pos
i !Pos
n (a
a :| a
a1 : [a]
as)
    | Pos
i Pos -> Pos -> Bool
forall a. Eq a => a -> a -> Bool
== Pos
n = (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [], NonEmpty a -> Split1 a
forall a. NonEmpty a -> Split1 a
SplitGT (a
a1 a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as))
    | Bool
otherwise =
        let (NonEmpty a
ys, Split1 a
y) = Pos -> Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
go (Pos -> Pos
succP Pos
i) Pos
n (a
a1 a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as)
         in (a
a a -> NonEmpty a -> NonEmpty a
forall a. a -> NonEmpty a -> NonEmpty a
N.<| NonEmpty a
ys, Split1 a
y)

-- | split a nonempty list but has to have enough elements else fails
splitAt1GE :: Pos -> NonEmpty a -> Either String (NonEmpty a, [a])
splitAt1GE :: Pos -> NonEmpty a -> Either String (NonEmpty a, [a])
splitAt1GE Pos
n NonEmpty a
as =
  let (NonEmpty a
ns, Split1 a
z) = Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
forall a. Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
splitAt1' Pos
n NonEmpty a
as
   in (NonEmpty a
ns,) ([a] -> (NonEmpty a, [a]))
-> Either String [a] -> Either String (NonEmpty a, [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Split1 a
z of
        SplitLT (Pos Int
len) -> String -> Either String [a]
forall a b. a -> Either a b
Left (String -> Either String [a]) -> String -> Either String [a]
forall a b. (a -> b) -> a -> b
$ String
"not enough elements: expected " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Pos -> Int
unP Pos
n) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" found " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len
        Split1 a
SplitEQ -> [a] -> Either String [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
forall a. Monoid a => a
mempty
        SplitGT NonEmpty a
ex -> [a] -> Either String [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
N.toList NonEmpty a
ex)

-- | repeatedly split a nonempty list
splitAts1 :: Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
splitAts1 :: Pos -> NonEmpty a -> NonEmpty (NonEmpty a)
splitAts1 Pos
i = (NonEmpty a -> (NonEmpty a, [a]))
-> NonEmpty a -> NonEmpty (NonEmpty a)
forall s a. (NonEmpty s -> (a, [s])) -> NonEmpty s -> NonEmpty a
unfoldr1NE (Pos -> NonEmpty a -> (NonEmpty a, [a])
forall a. Pos -> NonEmpty a -> (NonEmpty a, [a])
splitAt1 Pos
i) (NonEmpty a -> NonEmpty (NonEmpty a))
-> (NonEmpty a -> NonEmpty a)
-> NonEmpty a
-> NonEmpty (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty

-- | compares the length of a potentially infinite nonempty list with "n" and succeeds if they are the same
lengthExact1 :: Pos -> NonEmpty a -> Either String (NonEmpty a)
lengthExact1 :: Pos -> NonEmpty a -> Either String (NonEmpty a)
lengthExact1 Pos
n NonEmpty a
xs =
  let (NonEmpty a
as, Split1 a
z) = Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
forall a. Pos -> NonEmpty a -> (NonEmpty a, Split1 a)
splitAt1' Pos
n NonEmpty a
xs
   in case Split1 a
z of
        SplitLT (Pos Int
len) -> String -> Either String (NonEmpty a)
forall a b. a -> Either a b
Left (String -> Either String (NonEmpty a))
-> String -> Either String (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ String
"LT: not enough elements: expected " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Pos -> Int
unP Pos
n) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" found " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len
        Split1 a
SplitEQ -> NonEmpty a -> Either String (NonEmpty a)
forall a b. b -> Either a b
Right NonEmpty a
as
        SplitGT NonEmpty a
_ -> String -> Either String (NonEmpty a)
forall a b. a -> Either a b
Left (String -> Either String (NonEmpty a))
-> String -> Either String (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ String
"GT: too many elements: expected " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Pos -> Int
unP Pos
n)

-- | break up a nonempty list into all possible pairs of nonempty lists
splits1 :: forall a. NonEmpty a -> [(NonEmpty a, NonEmpty a)]
splits1 :: NonEmpty a -> [(NonEmpty a, NonEmpty a)]
splits1 (a
n :| [a]
ns) = ([a], [a]) -> [(NonEmpty a, NonEmpty a)]
go ([a
n], [a]
ns)
 where
  go :: ([a], [a]) -> [(NonEmpty a, NonEmpty a)]
  go :: ([a], [a]) -> [(NonEmpty a, NonEmpty a)]
go = \case
    ([], [a]
_) -> []
    ([a]
_, []) -> []
    (a
a : [a]
as, a
b : [a]
bs) -> (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as, a
b a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
bs) (NonEmpty a, NonEmpty a)
-> [(NonEmpty a, NonEmpty a)] -> [(NonEmpty a, NonEmpty a)]
forall a. a -> [a] -> [a]
: ([a], [a]) -> [(NonEmpty a, NonEmpty a)]
go (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
b], [a]
bs)

-- | like 'Data.List.iterate' but allows termination using Maybe
iterateMaybe1' :: (a -> Maybe a) -> a -> NonEmpty a
iterateMaybe1' :: (a -> Maybe a) -> a -> NonEmpty a
iterateMaybe1' a -> Maybe a
f a
a0 = a
a0 a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| a -> [a]
go a
a0
 where
  go :: a -> [a]
go a
a = case a -> Maybe a
f a
a of
    Maybe a
Nothing -> []
    Just a
x -> a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a]
go a
x

-- | like 'iterateMaybe1'' with 'boolMaybe'
iterateMaybe1 :: (a -> Bool) -> (a -> a) -> a -> NonEmpty a
iterateMaybe1 :: (a -> Bool) -> (a -> a) -> a -> NonEmpty a
iterateMaybe1 a -> Bool
f a -> a
g = (a -> Maybe a) -> a -> NonEmpty a
forall a. (a -> Maybe a) -> a -> NonEmpty a
iterateMaybe1' ((a -> Bool) -> (a -> a) -> a -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
boolMaybe a -> Bool
f a -> a
g)

-- | iterate "n" times
iterateN1 :: Pos -> (a -> a) -> a -> NonEmpty a
iterateN1 :: Pos -> (a -> a) -> a -> NonEmpty a
iterateN1 Pos
n = Pos -> NonEmpty a -> NonEmpty a
forall a. Pos -> NonEmpty a -> NonEmpty a
take1 Pos
n (NonEmpty a -> NonEmpty a)
-> ((a -> a) -> a -> NonEmpty a) -> (a -> a) -> a -> NonEmpty a
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.@ (a -> a) -> a -> NonEmpty a
forall a. (a -> a) -> a -> NonEmpty a
N.iterate

-- | break up a nonempty list into a nonempty list of three parts
splits3 :: forall a. NonEmpty a -> NonEmpty ([a], a, [a])
splits3 :: NonEmpty a -> NonEmpty ([a], a, [a])
splits3 (a
n :| [a]
ns) = (([a], a, [a]) -> a -> ([a], a, [a]))
-> ([a], a, [a]) -> [a] -> NonEmpty ([a], a, [a])
forall (f :: * -> *) b a.
Foldable f =>
(b -> a -> b) -> b -> f a -> NonEmpty b
N.scanl ([a], a, [a]) -> a -> ([a], a, [a])
forall z. ([a], a, [a]) -> z -> ([a], a, [a])
f ([], a
n, [a]
ns) [a]
ns
 where
  f :: forall z. ([a], a, [a]) -> z -> ([a], a, [a])
  f :: ([a], a, [a]) -> z -> ([a], a, [a])
f ([a]
xs, a
y, [a]
zs') z
_ = case [a]
zs' of
    [] -> String -> ([a], a, [a])
forall a. HasCallStack => String -> a
programmError String
"splits3"
    a
z : [a]
zs -> ([a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
y], a
z, [a]
zs)

-- | like 'Data.List.span' but applies the predicate to adjacent elements
spanAdjacent1 :: (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
spanAdjacent1 :: (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
spanAdjacent1 a -> a -> Bool
p (a
a0 :| [a]
as0) = ([a] -> NonEmpty a) -> ([a], [a]) -> (NonEmpty a, [a])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
a0 a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|) (a -> [a] -> ([a], [a])
go a
a0 [a]
as0)
 where
  go :: a -> [a] -> ([a], [a])
go a
a' = \case
    [] -> ([], [])
    a
a : [a]
as
      | a -> a -> Bool
p a
a' a
a -> ([a] -> [a]) -> ([a], [a]) -> ([a], [a])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (a -> [a] -> ([a], [a])
go a
a [a]
as)
      | Bool
otherwise -> ([], a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
as)

-- | like 'Data.List.break' but applies the predicate to adjacent elements
breakAdjacent1 :: (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
breakAdjacent1 :: (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
breakAdjacent1 a -> a -> Bool
p = (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
forall a. (a -> a -> Bool) -> NonEmpty a -> (NonEmpty a, [a])
spanAdjacent1 (Bool -> Bool
not (Bool -> Bool) -> (a -> a -> Bool) -> a -> a -> Bool
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.@ a -> a -> Bool
p)

-- | append a list with a nonempty list
appendL1 :: [a] -> NonEmpty a -> NonEmpty a
appendL1 :: [a] -> NonEmpty a -> NonEmpty a
appendL1 [a]
as NonEmpty a
bs = (a -> NonEmpty a -> NonEmpty a) -> NonEmpty a -> [a] -> NonEmpty a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> NonEmpty a -> NonEmpty a
forall a. a -> NonEmpty a -> NonEmpty a
N.cons NonEmpty a
bs [a]
as

-- | append a nonempty list with a list
appendR1 :: NonEmpty a -> [a] -> NonEmpty a
appendR1 :: NonEmpty a -> [a] -> NonEmpty a
appendR1 (a
a :| [a]
as) [a]
bs = a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| ([a]
as [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a]
bs)

-- | set a value at an index starting at one
setAt1 :: Pos -> a -> NonEmpty a -> Maybe (NonEmpty a)
setAt1 :: Pos -> a -> NonEmpty a -> Maybe (NonEmpty a)
setAt1 Pos
i = Pos -> (a -> a) -> NonEmpty a -> Maybe (NonEmpty a)
forall a. Pos -> (a -> a) -> NonEmpty a -> Maybe (NonEmpty a)
updateAt1 Pos
i ((a -> a) -> NonEmpty a -> Maybe (NonEmpty a))
-> (a -> a -> a) -> a -> NonEmpty a -> Maybe (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a b. a -> b -> a
const

-- | update a value at an index starting at one
updateAt1 :: Pos -> (a -> a) -> NonEmpty a -> Maybe (NonEmpty a)
updateAt1 :: Pos -> (a -> a) -> NonEmpty a -> Maybe (NonEmpty a)
updateAt1 (Pos Int
i) a -> a
f NonEmpty a
ns =
  case Int -> NonEmpty a -> ([a], [a])
forall a. Int -> NonEmpty a -> ([a], [a])
N.splitAt (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) NonEmpty a
ns of
    ([], a
b : [a]
bs) -> NonEmpty a -> Maybe (NonEmpty a)
forall a. a -> Maybe a
Just (a -> a
f a
b a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
bs)
    (a
a : [a]
as, a
b : [a]
bs) -> NonEmpty a -> Maybe (NonEmpty a)
forall a. a -> Maybe a
Just (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ (a -> a
f a
b a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
bs))
    ([a]
_, []) -> Maybe (NonEmpty a)
forall a. Maybe a
Nothing

-- | get a value at an index starting at one
at1 :: Pos -> NonEmpty a -> Maybe a
at1 :: Pos -> NonEmpty a -> Maybe a
at1 (Pos Int
i) NonEmpty a
ns =
  case Int -> NonEmpty a -> ([a], [a])
forall a. Int -> NonEmpty a -> ([a], [a])
N.splitAt (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) NonEmpty a
ns of
    ([a]
_, a
b : [a]
_) -> a -> Maybe a
forall a. a -> Maybe a
Just a
b
    ([a]
_, []) -> Maybe a
forall a. Maybe a
Nothing

-- | generate a repeated nonempty list of values for a fixed size
replicateP :: Pos -> a -> NonEmpty a
replicateP :: Pos -> a -> NonEmpty a
replicateP (Pos Int
i) a
a = a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
a

-- | length of nonempty list
lengthP :: Foldable1 t => t a -> Pos
lengthP :: t a -> Pos
lengthP = HasCallStack => String -> Int -> Pos
String -> Int -> Pos
unsafePos String
"lengthP" (Int -> Pos) -> (t a -> Int) -> t a -> Pos
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> Int
forall a. NonEmpty a -> Int
N.length (NonEmpty a -> Int) -> (t a -> NonEmpty a) -> t a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
toNonEmpty
{-# INLINE lengthP #-}

-- | generate a nonempty list of units for a fixed size
units1 :: Pos -> NonEmpty ()
units1 :: Pos -> NonEmpty ()
units1 = Pos -> NonEmpty ()
forall (l :: * -> *) a.
(IsList (l a), Item (l a) ~ ()) =>
Pos -> l a
unitsF

-- | generate a nonempty list of units for a given container of the given size
unitsF :: forall l a. (GE.IsList (l a), GE.Item (l a) ~ ()) => Pos -> l a
unitsF :: Pos -> l a
unitsF = [()] -> l a
forall l. IsList l => [Item l] -> l
GE.fromList ([()] -> l a) -> (Pos -> [()]) -> Pos -> l a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> () -> [()]) -> () -> Int -> [()]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> () -> [()]
forall a. Int -> a -> [a]
replicate () (Int -> [()]) -> (Pos -> Int) -> Pos -> [()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pos -> Int
unP

-- | sum of nonempty list of 'Pos' values
sumP :: Foldable1 t => t Pos -> Pos
sumP :: t Pos -> Pos
sumP = (Pos -> Pos -> Pos) -> t Pos -> Pos
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
L.foldr1 Pos -> Pos -> Pos
(+!)
{-# INLINE sumP #-}