module Printf where

open import Level using (0ℓ)
open import StateOfTheArt
  using ( Σ; _,_
        ; _≡_; refl
        )
open import N-ary
open import Function
open import Data.List.Base using (List; []; _∷_)
open import Data.Nat.Base using (; zero; suc)
open import Data.String using (String; concat)
open import Data.Nat.Show

data Chunk : Set where
  Nat  : Chunk
  Raw  : String  Chunk

Format : Set
Format = List Chunk

size : Format  
size []             = zero
size (Nat     f)  = suc (size f)
size (Raw _   f)  = size f

0ℓs :  {n}  Levels n
0ℓs {zero}  = _
0ℓs {suc n} = 0ℓ , 0ℓs

format : (fmt : Format)  Sets (size fmt) 0ℓs
format []            = _
format (Nat     f)  =  , format f
format (Raw _   f)  = format f

assemble :  fmt  Product _ (format fmt)  List String
assemble []              vs        = []
assemble (Nat     fmt)  (n , vs)  = show n  assemble fmt vs
assemble (Raw s   fmt)  vs        = s  assemble fmt vs

printf :  fmt  Arrows _ (format fmt) String
printf fmt = curryₙ (size fmt) (concat  assemble fmt)

lessThan :     String
lessThan = printf (Nat  Raw " < "  Nat  [])

_ : lessThan 2 5  "2 < 5"
_ = refl