module Data.NonNull (
NonNull
, fromNullable
, nonNull
, toNullable
, fromNonEmpty
, ncons
, nuncons
, splitFirst
, nfilter
, nfilterM
, nReplicate
, head
, tail
, last
, init
, ofoldMap1
, ofold1
, ofoldr1
, ofoldl1'
, maximum
, maximumBy
, minimum
, minimumBy
, (<|)
) where
import Prelude hiding (head, tail, init, last, reverse, seq, filter, replicate, maximum, minimum)
import Data.MonoTraversable
import Data.Sequences
import Control.Exception.Base (Exception, throw)
import Data.Data
import qualified Data.List.NonEmpty as NE
import Data.MinLen
data NullError = NullError String deriving (Show, Typeable)
instance Exception NullError
type NonNull mono = MinLen (Succ Zero) mono
fromNullable :: MonoFoldable mono => mono -> Maybe (NonNull mono)
fromNullable = toMinLen
nonNull :: MonoFoldable mono => mono -> NonNull mono
nonNull nullable = case fromNullable nullable of
Nothing -> throw $ NullError "Data.NonNull.nonNull (NonNull default): expected non-null"
Just xs -> xs
toNullable :: NonNull mono -> mono
toNullable = unMinLen
fromNonEmpty :: IsSequence seq => NE.NonEmpty (Element seq) -> NonNull seq
fromNonEmpty = nonNull . fromList . NE.toList
ncons :: SemiSequence seq => Element seq -> seq -> NonNull seq
ncons x xs = nonNull $ cons x xs
nuncons :: IsSequence seq => NonNull seq -> (Element seq, Maybe (NonNull seq))
nuncons xs = case uncons $ toNullable xs of
Nothing -> error "Data.NonNull.nuncons: data structure is null, it should be non-null"
Just (x, xsNullable) -> (x, fromNullable xsNullable)
splitFirst :: IsSequence seq => NonNull seq -> (Element seq, seq)
splitFirst xs = case uncons $ toNullable xs of
Nothing -> error "Data.NonNull.splitFirst: data structure is null, it should be non-null"
Just tup -> tup
nfilter :: IsSequence seq => (Element seq -> Bool) -> NonNull seq -> seq
nfilter f = filter f . toNullable
nfilterM :: (Monad m, IsSequence seq) => (Element seq -> m Bool) -> NonNull seq -> m seq
nfilterM f = filterM f . toNullable
nReplicate :: IsSequence seq => Index seq -> Element seq -> NonNull seq
nReplicate i = nonNull . replicate (max 1 i)
tail :: IsSequence seq => NonNull seq -> seq
tail = tailEx . toNullable
init :: IsSequence seq => NonNull seq -> seq
init = initEx . toNullable
infixr 5 <|
(<|) :: SemiSequence seq => Element seq -> NonNull seq -> NonNull seq
x <| y = ncons x (toNullable y)