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
, (<|)
, toMinList
) where
import Prelude hiding (head, tail, init, last, reverse, seq, filter, replicate, maximum, minimum)
import Control.Arrow (second)
import Control.Exception.Base (Exception, throw)
import Data.Data
import qualified Data.List.NonEmpty as NE
import Data.Maybe (fromMaybe)
import Data.MinLen
import Data.MonoTraversable
import Data.Sequences
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 =
fromMaybe (throw $ NullError "Data.NonNull.nonNull (NonNull default): expected non-null")
$ fromNullable nullable
toNullable :: NonNull mono -> mono
toNullable = unMinLen
fromNonEmpty :: IsSequence seq => NE.NonEmpty (Element seq) -> NonNull seq
fromNonEmpty = nonNull . fromList . NE.toList
toMinList :: NE.NonEmpty a -> NonNull [a]
toMinList = fromNonEmpty
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 =
second fromNullable
$ fromMaybe (error "Data.NonNull.nuncons: data structure is null, it should be non-null")
$ uncons (toNullable xs)
splitFirst :: IsSequence seq => NonNull seq -> (Element seq, seq)
splitFirst xs =
fromMaybe (error "Data.NonNull.splitFirst: data structure is null, it should be non-null")
$ uncons (toNullable xs)
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)