content: {-# LANGUAGE DeriveFunctor #-}
  {-# LANGUAGE DeriveFoldable #-}
  {-# LANGUAGE DeriveTraversable #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  module Data.Aeson.Config.Types where
  
  import           Imports
  
  import           Data.Bitraversable
  import           Data.Bifoldable
  
  import           Data.Aeson.Config.FromValue
  
  newtype List a = List {fromList :: [a]}
    deriving (Eq, Show, Functor, Foldable, Traversable, Semigroup, Monoid)
  
  instance FromValue a => FromValue (List a) where
    fromValue v = List <$> case v of
      Array _ -> fromValue v
      _ -> return <$> fromValue v
  
  fromMaybeList :: Maybe (List a) -> [a]
  fromMaybeList = maybe [] fromList
  
  data Product a b = Product a b
    deriving (Eq, Show, Functor, Foldable, Traversable)
  
  instance (Semigroup a, Semigroup b, Monoid a, Monoid b) => Monoid (Product a b) where
    mempty = Product mempty mempty
    mappend = (<>)
  
  instance (Semigroup a, Semigroup b) => Semigroup (Product a b) where
    Product a1 b1 <> Product a2 b2 = Product (a1 <> a2) (b1 <> b2)
  
  instance Bifunctor Product where
    bimap fa fb (Product a b) = Product (fa a) (fb b)
  
  instance Bifoldable Product where
    bifoldMap = bifoldMapDefault
  
  instance Bitraversable Product where
    bitraverse fa fb (Product a b) = Product <$> fa a <*> fb b
  
  instance (FromValue a, FromValue b) => FromValue (Product a b) where
    fromValue v = Product <$> fromValue v <*> fromValue v
  