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

module Data.List.Smart where

open import Prelude

open import Data.Nat.Properties using (module Eqℕ)

infixr 5 _∷′_ _++′_
data List {a} (A : Type a) : Type a where
  []′ : List A
  _∷′_ : A  List A  List A
  _++′_ : List A  List A  List A

sz′ : List A    
sz′ []′ k = k
sz′ (x ∷′ xs) k = k
sz′ (xs ++′ ys) k = suc (sz′ xs (sz′ ys k))

sz : List A  
sz []′ = zero
sz (x ∷′ xs) = zero
sz (xs ++′ ys) = sz′ xs (sz ys)

open Eqℕ

_HasSize_ : List A    Type
xs HasSize n = T (sz xs ≡ᴮ n)

data ListView {a} (A : Type a) : Type a where
  Nil : ListView A
  Cons : A  List A  ListView A

viewˡ : List A  ListView A
viewˡ xs = go xs (sz xs) (complete (sz xs))
  where
  go : (xs : List A)  (n : )  xs HasSize n  ListView A
  go  []′                  n       p = Nil
  go  (x ∷′ xs)            n       p = Cons x xs
  go  ((x ∷′ xs) ++′ ys)   n       p = Cons x (xs ++′ ys)
  go  ([]′ ++′ ys)         n       p = go ys n p
  go  ((xs ++′ ys) ++′ zs) (suc n) p = go (xs ++′ (ys ++′ zs)) n p