{-# OPTIONS --cubical --safe #-}

module Container.List.Isomorphism where

open import Prelude
open import Container
open import Container.List
open import Data.Fin
open import Data.List using (tabulate; length ; _!_) renaming (_∷_ to _L∷_; [] to L[]; List to š•ƒ)
open import Data.List.Properties

ā„’ā†’š•ƒ : List A → š•ƒ A
ā„’ā†’š•ƒ = uncurry tabulate

š•ƒā†’ā„’ : š•ƒ A → List A
š•ƒā†’ā„’ xs .fst = length xs
š•ƒā†’ā„’ xs .snd i = xs ! i

ā„’ā†’š•ƒā†’ā„’ : āˆ€ n (xs : Fin n → A) → š•ƒā†’ā„’ (ā„’ā†’š•ƒ (n , xs)) ≔ (n , xs)
ā„’ā†’š•ƒā†’ā„’ n xs i .fst = tab-length n xs i
ā„’ā†’š•ƒā†’ā„’ n xs i .snd = tab-id n xs i

š•ƒā†’ā„’ā†’š•ƒ : āˆ€ (xs : š•ƒ A) → ā„’ā†’š•ƒ (š•ƒā†’ā„’ xs) ≔ xs
š•ƒā†’ā„’ā†’š•ƒ L[] _ = L[]
š•ƒā†’ā„’ā†’š•ƒ (x L∷ xs) i = x L∷ š•ƒā†’ā„’ā†’š•ƒ xs i

š•ƒā‡”ā„’ : š•ƒ A ⇔ List A
š•ƒā‡”ā„’ .fun = š•ƒā†’ā„’
š•ƒā‡”ā„’ .inv = ā„’ā†’š•ƒ
š•ƒā‡”ā„’ .rightInv  = uncurry ā„’ā†’š•ƒā†’ā„’
š•ƒā‡”ā„’ .leftInv = š•ƒā†’ā„’ā†’š•ƒ