ocaml - Type-safe template variable substitution -


i had idea of type-safe templating language use polymorphic variants source of type-safe variables can substituted text, example:

type 'a t = var of 'a | text of string | join of 'a t * 'a t    let rec render ~vars = function   | text source -> source   | var label -> vars label   | join (left, right) -> render left ~vars ^ render right ~vars  let result = render (join (var `foo, text "bar")) ~vars:(function `foo -> "foo");;  let () = assert (result = "foobar")   

this fine: compiler enforce don't forget substitution variable, or don't have typo in variable name—thanks polymorphic variants.

however, find 2 problems:

  1. you can accidentally supply unused variable.

  2. if template contains no variables, still forced supply ~vars function, , 1 work fun _ -> "" or fun _ -> assert false, compromizes type-safety in case template ever changes.

i'm looking advice on problems above, appreciate applicable advice on api design.

nothing force use polymorphic variants. have void type guaranteed different every polymorphic variant.

type void let empty_vars : void -> string = fun _ assert false 

when apply empty template, end with

let result = render (text "bar") ~vars:empty_vars 

that way, if later add variable template, notice through type error.

for unused variables, best can suggest not use polymorphic variants:

type v = foo let result = render (join (var foo, text "bar")) ~vars:(function foo -> "foo");; 

this catch unused cases in function definition, of course if remove part of template, won't notice anything.

one other solution have similar properties may, or may not suit taste use objects.

let rec render ~vars = function   | text source -> source   | var label -> label vars   | join (left, right) -> render left ~vars ^ render right ~vars   let foo v = v#foo let result = render (join (var foo, text "bar")) ~vars:object method foo = "foo" end 

that way can keep same pattern when no variables used:

let result = render (text "bar") ~vars:object end 

but still no unused variable check.


Comments

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

python - Pygame screen.blit not working -

c# - Web API response xml language -