module Cubical.HITs.James.Base where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Pointed
private
  variable
    β β' : Level
module _
  ((X , xβ) : Pointed β) where
  infixr 5 _β·_
  
  data James : Type β where
    []   : James
    _β·_  : X β James β James
    unit : (xs : James) β xs β‘ xβ β· xs
  Jamesβ : Pointed β
  Jamesβ = James , []
module _
  {Xβ@(X , xβ) : Pointed β} where
  infixr 5 _++_
  infixl 5 _β·Κ³_
  [_] : X β James Xβ
  [ x ] = x β· []
  _++_ : James Xβ β James Xβ β James Xβ
  [] ++ ys = ys
  (x β· xs) ++ ys = x β· xs ++ ys
  (unit xs i) ++ ys = unit (xs ++ ys) i
  ++β : (xs : James Xβ) β xs β‘ xs ++ [ xβ ]
  ++β [] = unit []
  ++β (x β· xs) i = x β· ++β xs i
  ++β (unit xs i) j = unit (++β xs j) i
  rev : James Xβ β James Xβ
  rev [] = []
  rev (x β· xs) = rev xs ++ [ x ]
  rev (unit xs i) = ++β (rev xs) i
  _β·Κ³_ : James Xβ β X β James Xβ
  xs β·Κ³ x = xs ++ x β· []
map : {X : Pointed β}{Y : Pointed β'} β (X ββ Y) β James X β James Y
map f [] = []
map f (x β· xs) = f .fst x β· map f xs
map f (unit xs i) = (unit (map f xs) β (Ξ» i β f .snd (~ i) β· map f xs)) i
mapβ : {X : Pointed β}{Y : Pointed β'} β (X ββ Y) β Jamesβ X ββ Jamesβ Y
mapβ f .fst = map f
mapβ f .snd = refl