{-# LANGUAGE Safe #-}

{- |
Copyright:  (c) 2016 Stephen Diehl
            (c) 2016-2018 Serokell
            (c) 2018-2019 Kowainik
SPDX-License-Identifier: MIT
Maintainer: Kowainik <xrom.xkov@gmail.com>

This module contains safe functions to work with list type in terms of 'NonEmpty'.
-}

module Relude.List.NonEmpty
       ( viaNonEmpty
       , whenNotNull
       , whenNotNullM
       ) where

import Relude.Applicative (Applicative, pass)
import Relude.Function ((.))
import Relude.Functor (fmap)
import Relude.List.Reexport (NonEmpty (..), nonEmpty)
import Relude.Monad (Maybe (..), Monad (..))


-- $setup
-- >>> import Relude

{- | For safe work with lists using functinons for 'NonEmpty'.

>>> viaNonEmpty head [1]
Just 1
>>> viaNonEmpty head []
Nothing
-}
viaNonEmpty :: (NonEmpty a -> b) -> [a] -> Maybe b
viaNonEmpty :: (NonEmpty a -> b) -> [a] -> Maybe b
viaNonEmpty f :: NonEmpty a -> b
f = (NonEmpty a -> b) -> Maybe (NonEmpty a) -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty a -> b
f (Maybe (NonEmpty a) -> Maybe b)
-> ([a] -> Maybe (NonEmpty a)) -> [a] -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe (NonEmpty a)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty
{-# INLINE viaNonEmpty #-}

{- | Performs given action over 'NonEmpty' list if given list is non empty.

>>> whenNotNull [] $ \(b :| _) -> print (not b)
>>> whenNotNull [False,True] $ \(b :| _) -> print (not b)
True
-}
whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
whenNotNull :: [a] -> (NonEmpty a -> f ()) -> f ()
whenNotNull []     _ = f ()
forall (f :: * -> *). Applicative f => f ()
pass
whenNotNull (x :: a
x:xs :: [a]
xs) f :: NonEmpty a -> f ()
f = NonEmpty a -> f ()
f (a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs)
{-# INLINE whenNotNull #-}

-- | Monadic version of 'whenNotNull'.
whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
whenNotNullM :: m [a] -> (NonEmpty a -> m ()) -> m ()
whenNotNullM ml :: m [a]
ml f :: NonEmpty a -> m ()
f = m [a]
ml m [a] -> ([a] -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \l :: [a]
l -> [a] -> (NonEmpty a -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
[a] -> (NonEmpty a -> f ()) -> f ()
whenNotNull [a]
l NonEmpty a -> m ()
f
{-# INLINE whenNotNullM #-}