{-# OPTIONS --safe --without-K  #-}

module Lists where

open import Agda.Primitive using (_⊔_)

infixr 5 _∷_
data List {a} (A : Set a) : Set a where
  [] : List A
  _∷_ : A → List A → List A

module _ {a b} {A : Set a} {B : Set b} where
  foldr : (A → B → B) → B → List A → B
  foldr f b [] = b
  foldr f b (x ∷ xs) = f x (foldr f b xs)

  foldl : (B → A → B) → B → List A → B
  foldl f b [] = b
  foldl f b (x ∷ xs) = foldl f (f b x) xs

record IsList {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where
  field [_]  : A → List B
open IsList ⦃ ... ⦄ public

instance
  nil : ∀ {a} {A : Set a} → IsList A A
  [_] ⦃ nil ⦄ = _∷ []

infixr 4 _,_
record Cons {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where
  constructor _,_
  field
    head : A
    tail : B

instance
  cons : ∀ {b} {B : Set b} {a} {A : Set a}
    → ⦃ _ : IsList A B ⦄
    → IsList (Cons B A) B
  [_] ⦃ cons ⦄ (x , xs) = x ∷ [ xs ]