{-# LANGUAGE RankNTypes #-}
module Fresnel.Monoid.Cons
( -- * Cons lists
  Cons(..)
  -- * Construction
, singleton
, cons
, nil
) where

import Data.Foldable (toList)

-- Cons lists

newtype Cons a = Cons { Cons a -> forall r. (a -> r -> r) -> r -> r
runCons :: forall r . (a -> r -> r) -> r -> r }

instance Show a => Show (Cons a) where
  showsPrec :: Int -> Cons a -> ShowS
showsPrec Int
_ = [a] -> ShowS
forall a. Show a => [a] -> ShowS
showList ([a] -> ShowS) -> (Cons a -> [a]) -> Cons a -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cons a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

instance Semigroup (Cons a) where
  Cons forall r. (a -> r -> r) -> r -> r
a1 <> :: Cons a -> Cons a -> Cons a
<> Cons forall r. (a -> r -> r) -> r -> r
a2 = (forall r. (a -> r -> r) -> r -> r) -> Cons a
forall a. (forall r. (a -> r -> r) -> r -> r) -> Cons a
Cons (\ a -> r -> r
cons -> (a -> r -> r) -> r -> r
forall r. (a -> r -> r) -> r -> r
a1 a -> r -> r
cons (r -> r) -> (r -> r) -> r -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> r -> r) -> r -> r
forall r. (a -> r -> r) -> r -> r
a2 a -> r -> r
cons)

instance Monoid (Cons a) where
  mempty :: Cons a
mempty = Cons a
forall a. Cons a
nil

instance Foldable Cons where
  foldMap :: (a -> m) -> Cons a -> m
foldMap a -> m
f (Cons forall r. (a -> r -> r) -> r -> r
r) = (a -> m -> m) -> m -> m
forall r. (a -> r -> r) -> r -> r
r (m -> m -> m
forall a. Monoid a => a -> a -> a
mappend (m -> m -> m) -> (a -> m) -> a -> m -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m
f) m
forall a. Monoid a => a
mempty
  foldr :: (a -> b -> b) -> b -> Cons a -> b
foldr a -> b -> b
f b
z (Cons forall r. (a -> r -> r) -> r -> r
r) = (a -> b -> b) -> b -> b
forall r. (a -> r -> r) -> r -> r
r a -> b -> b
f b
z

instance Functor Cons where
  fmap :: (a -> b) -> Cons a -> Cons b
fmap a -> b
f (Cons forall r. (a -> r -> r) -> r -> r
r) = (a -> Cons b -> Cons b) -> Cons b -> Cons b
forall r. (a -> r -> r) -> r -> r
r (b -> Cons b -> Cons b
forall a. a -> Cons a -> Cons a
cons (b -> Cons b -> Cons b) -> (a -> b) -> a -> Cons b -> Cons b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) Cons b
forall a. Cons a
nil


-- Construction

singleton :: a -> Cons a
singleton :: a -> Cons a
singleton a
a = (forall r. (a -> r -> r) -> r -> r) -> Cons a
forall a. (forall r. (a -> r -> r) -> r -> r) -> Cons a
Cons (\ a -> r -> r
cons r
nil -> a -> r -> r
cons a
a r
nil)

cons :: a -> Cons a -> Cons a
cons :: a -> Cons a -> Cons a
cons a
a (Cons forall r. (a -> r -> r) -> r -> r
as) = (forall r. (a -> r -> r) -> r -> r) -> Cons a
forall a. (forall r. (a -> r -> r) -> r -> r) -> Cons a
Cons (\ a -> r -> r
cons -> a -> r -> r
cons a
a (r -> r) -> (r -> r) -> r -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> r -> r) -> r -> r
forall r. (a -> r -> r) -> r -> r
as a -> r -> r
cons)

nil :: Cons a
nil :: Cons a
nil = (forall r. (a -> r -> r) -> r -> r) -> Cons a
forall a. (forall r. (a -> r -> r) -> r -> r) -> Cons a
Cons (\ a -> r -> r
_ r
nil -> r
nil)