open import FRP.JS.Nat using (; zero ; suc )
open import FRP.JS.Bool using ( Bool ; true ; false ; _∧_ )
open import FRP.JS.Maybe using ( Maybe ; just ; nothing )

module FRP.JS.List where

infixr 4 _∷_ _++_
infixr 2 _≟[_]_

data List {α} (A : Set α) : Set α where
  [] : List A
  _∷_ : (a : A)  (as : List A)  List A

{-# BUILTIN LIST List #-}
{-# BUILTIN NIL  []   #-}
{-# BUILTIN CONS _∷_  #-}

[_] :  {α} {A : Set α}  A  List A
[ x ] = x  []

_++_ :  {α} {A : Set α}  List A  List A  List A
[]       ++ ys = ys
(x  xs) ++ ys = x  (xs ++ ys)

map :  {α β} {A : Set α} {B : Set β}  (A  B)  List A  List B
map f []       = []
map f (x  xs) = f x  map f xs

foldr :  {α β} {A : Set α} {B : Set β}  (A  B  B)  B  List A  B
foldr c n []       = n
foldr c n (x  xs) = c x (foldr c n xs)

foldl :  {α β} {A : Set α} {B : Set β}  (A  B  A)  A  List B  A
foldl c n []       = n
foldl c n (x  xs) = foldl c (c n x) xs

buildAppend :  {α} {A : Set α}  List A  (  A)    List A
buildAppend as f zero    = as
buildAppend as f (suc n) = buildAppend (f n  as) f n

build :  {α} {A : Set α}  (  A)    List A
build = buildAppend []

length :  {α} {A : Set α}  List A  
length = foldr  a n  suc n) zero

lookup :  {α} {A : Set α}  List A    Maybe A
lookup []       x       = nothing
lookup (a  as) zero    = just a
lookup (a  as) (suc n) = lookup as n

_≟[_]_ :  {α β} {A : Set α} {B : Set β}  List A  (A  B  Bool)  List B  Bool
[]       ≟[ p ] []       = true
(a  as) ≟[ p ] (b  bs) = (p a b)  (as ≟[ p ] bs)
_        ≟[ p ] _        = false