{-# OPTIONS --safe --without-K #-}
module stdlib.Data.Vec.Instances where

open import Level
open import Algebra
open import Data.Vec
open import Data.Vec.Properties hiding (zipWith-assoc; zipWith-identityˡ; zipWith-identityʳ; zipWith-comm)
open import Data.Nat using ()

open import Relation.Binary
open import Algebra
open import Data.Product.Base using (_×_; zip; _,_; map; _<*>_; uncurry)
open import Level using (Level; _⊔_)

open import Data.Vec.Relation.Binary.Pointwise.Inductive 

private
  variable
    a b  ℓ₁ ℓ₂ : Level
    A : Set a
    n : 

------------------------------------------------------------------------
-- Raw bundles

module _ (n : ) where
  rawMagma : RawMagma a   RawMagma a (a  )
  rawMagma M = record
    { Carrier = Vec M.Carrier n
    ; _≈_     = Pointwise M._≈_
    ; _∙_     = zipWith M._∙_
    } where module M = RawMagma M
  
  rawMonoid : RawMonoid a   RawMonoid a (a  )
  rawMonoid M = record
    { Carrier = Vec M.Carrier n
    ; _≈_     = Pointwise M._≈_
    ; _∙_     = zipWith M._∙_
    ; ε       = replicate n M.ε
    } where module M = RawMonoid M

------------------------------------------------------------------------
-- Bundles

module _ (n : ) where

  magma : Magma a   Magma a (a  )
  magma M = record
    { Carrier = Vec M.Carrier n
    ; _≈_     = Pointwise M._≈_
    ; _∙_     = zipWith M._∙_
    ; isMagma = record
      { isEquivalence = isEquivalence M.isEquivalence n
      ; ∙-cong = zipWith-cong M.∙-cong
      }
    } where module M = Magma M

  semigroup : Semigroup a   Semigroup a (a  )
  semigroup G = record
    { isSemigroup = record
      { isMagma = Magma.isMagma (magma G.magma)
      ; assoc = zipWith-assoc G.assoc
      }
    } where module G = Semigroup G

  monoid : Monoid a   Monoid a (a  )
  monoid M = record
    { ε = replicate n M.ε
    ; isMonoid = record
      { isSemigroup = Semigroup.isSemigroup (semigroup M.semigroup)
      ; identity = zipWith-identityˡ M.identityˡ
                 , zipWith-identityʳ M.identityʳ
      }
    } where module M = Monoid M

  commutativeMonoid : CommutativeMonoid a 
                     CommutativeMonoid a (a  )
  commutativeMonoid M = record
    { isCommutativeMonoid = record
      { isMonoid = Monoid.isMonoid (monoid M.monoid)
      ; comm = zipWith-comm M.comm
      }
    } where module M = CommutativeMonoid M