{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
#if __GLASGOW_HASKELL__ < 800
{-# LANGUAGE FlexibleContexts #-}
#endif
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell, DeriveFoldable, DeriveFunctor, GeneralizedNewtypeDeriving, DeriveTraversable #-}
module Language.Rust.Parser.NonEmpty (
NonEmpty(..),
listCons,
head, tail,
reverse, last, init, (<|), (|:), (|>)
) where
import Prelude hiding (head, tail, reverse, init, last)
import qualified Data.List.NonEmpty as N
import Data.Data ( Data(..) )
import Control.DeepSeq ( NFData )
import Data.Semigroup (Semigroup(..))
import GHC.Exts (IsList(..))
newtype NonEmpty a = NonEmpty (N.NonEmpty a)
deriving (Foldable, Eq, Ord, Show, Functor, Data, NFData, Traversable)
instance IsList (NonEmpty a) where
type Item (NonEmpty a) = a
fromList (a:as) = NonEmpty $ a N.:| as
fromList [] = errorWithoutStackTrace "NonEmpty.fromList: empty list"
toList ~(NonEmpty (a N.:| as)) = a : as
instance Semigroup (NonEmpty a) where
(NonEmpty (a N.:| as)) <> ~(NonEmpty (b N.:| bs)) = NonEmpty $ a N.:| (as ++ b : bs)
listCons :: a -> [a] -> NonEmpty a
listCons a as = NonEmpty $ a N.:| as
head :: NonEmpty a -> a
head (NonEmpty as) = N.head as
tail :: NonEmpty a -> [a]
tail (NonEmpty as) = N.tail as
reverse :: NonEmpty a -> NonEmpty a
reverse (NonEmpty as) = NonEmpty $ N.reverse as
init :: NonEmpty a -> [a]
init (NonEmpty as) = N.init as
last :: NonEmpty a -> a
last (NonEmpty as) = N.last as
(<|) :: a -> NonEmpty a -> NonEmpty a
(<|) a (NonEmpty as) = NonEmpty $ a N.<| as
(|:) :: [a] -> a -> NonEmpty a
[] |: y = NonEmpty $ y N.:| []
(x:xs) |: y = NonEmpty $ x N.:| (xs ++ [y])
(|>) :: NonEmpty a -> a -> NonEmpty a
(|>) (NonEmpty (x N.:| xs)) y = NonEmpty $ x N.:| (xs ++ [y])