I am building a small DSL for iOS' autolayout feature. Obviously I want to have a typesafe way to define autolayouts instead of doing VSL. I came up with the following:
//in reality this will be a Xamarin/iOS View type View = | View type Constraint = | Max of int | Min of int | Eq of int | Both of int * int type Element = | Gap of Constraint | Part of View * Constraint let horizontal superview : Element list =  let max v = Max v let min v = Min v let eq v = Eq v let minmax min max = Both(min, max) let gap c es = Gap c :: es let view v c es = Part (v, c) :: es //transform needs to implement the real autolayouting. //not yet done let transform es = List.rev es let super_view, left_view, middle_view, right_view = View, View, View, View horizontal super_view |> gap (min 20) |> view left_view (min 20) |> gap (max 30) |> view middle_view (eq 45) |> gap (eq 50) |> view right_view (minmax 20 100) |> gap (max 0) |> transform
I am sort of content with the design so far; for example, it has a pretty "fluid" touch to it. However I am asking myself if there are better ways to do it.
One particular issue is the simple fact that every definition is a intersection of "gaps" and "views" starting with a "gap" and ending with a "gap". Is there a possibility to "encode" such a design into types instead of doing it via runtime exceptions (which I would do now).