-- |
-- Module: Data.Greskell.NonEmptyLike
-- Description: Class of non-empty containers
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- @since 1.0.0.0
module Data.Greskell.NonEmptyLike
    ( NonEmptyLike (..)
    ) where

import qualified Data.Foldable      as F
import           Data.List.NonEmpty (NonEmpty (..))
import           Data.Semigroup     (Semigroup, (<>))
import qualified Data.Semigroup     as S

-- | Non-empty containers. Its cardinality is one or more.
--
-- @since 1.0.0.0
class F.Foldable t => NonEmptyLike t where
  -- | Make a container with a single value.
  singleton :: a -> t a
  -- | Append two containers.
  append :: t a -> t a -> t a
  -- | Convert the container to 'NonEmpty' list.
  toNonEmpty :: t a -> NonEmpty a

-- | 'append' is '<>' from 'Semigroup'.
instance NonEmptyLike NonEmpty where
  singleton :: forall a. a -> NonEmpty a
singleton a
a = a
a forall a. a -> [a] -> NonEmpty a
:| []
  append :: forall a. NonEmpty a -> NonEmpty a -> NonEmpty a
append = forall a. Semigroup a => a -> a -> a
(<>)
  toNonEmpty :: forall a. NonEmpty a -> NonEmpty a
toNonEmpty = forall a. a -> a
id

-- | 'append' is '<>' from 'Semigroup'.
instance NonEmptyLike S.First where
  singleton :: forall a. a -> First a
singleton = forall a. a -> First a
S.First
  append :: forall a. First a -> First a -> First a
append = forall a. Semigroup a => a -> a -> a
(<>)
  toNonEmpty :: forall a. First a -> NonEmpty a
toNonEmpty (S.First a
a) = forall (t :: * -> *) a. NonEmptyLike t => a -> t a
singleton a
a

-- | 'append' is '<>' from 'Semigroup'.
instance NonEmptyLike S.Last where
  singleton :: forall a. a -> Last a
singleton = forall a. a -> Last a
S.Last
  append :: forall a. Last a -> Last a -> Last a
append = forall a. Semigroup a => a -> a -> a
(<>)
  toNonEmpty :: forall a. Last a -> NonEmpty a
toNonEmpty (S.Last a
a) = forall (t :: * -> *) a. NonEmptyLike t => a -> t a
singleton a
a