module General.ListBuilder(
    ListBuilder, runListBuilder, newListBuilder
    ) where

import Data.Semigroup (Semigroup (..))
import Data.Monoid hiding ((<>))
import Prelude()

data ListBuilder a
    = Zero
    | One a
    | Add (ListBuilder a) (ListBuilder a)


instance Semigroup (ListBuilder a) where
    Zero <> x = x
    x <> Zero = x
    x <> y = Add x y

instance Monoid (ListBuilder a) where
    mempty = Zero
    mappend = (<>)

newListBuilder :: a -> ListBuilder a
newListBuilder = One

runListBuilder :: ListBuilder a -> [a]
runListBuilder x = f x []
    where
        f Zero acc = []
        f (One x) acc = x : acc
        f (Add x y) acc = f x (f y acc)