module Haskell.Data.List.NonEmpty where
open import Haskell.Prelude
hiding (NonEmpty; head; tail; toList; init; last)
open import Haskell.Data.Foldable1 using (Foldable1)
infixr 5 _:|_ _<|_
record NonEmpty (a : Type) : Type where
no-eta-equality
pattern
constructor _:|_
field
head : a
tail : List a
open NonEmpty public
toList : {a : Type} → NonEmpty a → List a
toList xs = head xs List.∷ tail xs
_<|_ : {a : Type} → a → NonEmpty a → NonEmpty a
x <| xs = x :| head xs List.∷ tail xs
cons = _<|_
singleton : {a : Type} → a → NonEmpty a
singleton x = x :| []
init : {a : Type} → NonEmpty a → List a
init = λ xs → helper (head xs) (tail xs)
module Init where
helper : {a : Type} → a → List a → List a
helper x [] = []
helper x (y List.∷ xs) = x List.∷ helper y xs
last : {a : Type} → NonEmpty a → a
last = λ xs → helper (head xs) (tail xs)
module Last where
helper : {a : Type} → a → List a → a
helper x [] = x
helper _ (y List.∷ xs) = helper y xs
private
bindNonEmpty : ∀ {a b} → NonEmpty a → (a → NonEmpty b) → NonEmpty b
bindNonEmpty xs f = head fx :| tail fx ++ fxs
where
fx = f (head xs)
fxs = tail xs >>= (toList ∘ f)
instance
iFunctorNonEmpty : Functor NonEmpty
iFunctorNonEmpty .fmap f xs = f (head xs) :| fmap f (tail xs)
iFunctorNonEmpty ._<$_ b xs = b ⦃ head xs ⦄ :| (b <$ tail xs)
iDefaultApplicativeNonEmpty : DefaultApplicative NonEmpty
iDefaultApplicativeNonEmpty .DefaultApplicative.pure x = x :| []
iDefaultApplicativeNonEmpty .DefaultApplicative._<*>_ fs xs =
bindNonEmpty fs λ f → bindNonEmpty xs λ x → f x :| []
iApplicativeNonEmpty : Applicative NonEmpty
iApplicativeNonEmpty = record {DefaultApplicative iDefaultApplicativeNonEmpty}
iDefaultMonadNonEmpty : DefaultMonad NonEmpty
iDefaultMonadNonEmpty .DefaultMonad._>>=_ = bindNonEmpty
iMonadNonEmpty : Monad NonEmpty
iMonadNonEmpty = record {DefaultMonad iDefaultMonadNonEmpty}
iSemigroupNonEmpty : ∀ {a} → Semigroup (NonEmpty a)
iSemigroupNonEmpty ._<>_ (x :| xs) ys = x :| xs ++ toList ys
iDefaultFoldableNonEmpty : DefaultFoldable NonEmpty
iDefaultFoldableNonEmpty .DefaultFoldable.foldMap f (x :| xs) = f x <> foldMap f xs
iFoldableNonEmpty : Foldable NonEmpty
iFoldableNonEmpty = record {DefaultFoldable iDefaultFoldableNonEmpty}
iFoldable1NonEmpty : Foldable1 NonEmpty
iFoldable1NonEmpty .Foldable1.foldMap1 f (x :| xs) = go (f x) xs
where
go : _ → List _ → _
go y [] = y
go y (x List.∷ xs) = y <> go (f x) xs