Yeah, this is pretty cool! We did actually consider using this kind of SRTP-based solution for HTML construction, but we decided against it because of the confusing error messages you can get from the compiler if you type something wrong.

We do have something similar to your type-checking inline though, but written using F# type tests: Doc.ToMixedDoc (see the implementation). It is used for C# support, where docs are constructed using methods taking params obj[] as argument.

By on 10/18/2017 12:41 AM ()

Excellent! Thank you for the tips. I replaced the hack with the following code and it seems to work well:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

    let toVal (o: obj) =
match o with
| :?      string   as t   -> Val.Constant t
| :?      int      as t   -> Val.Constant t |> As<Val<string>>
| :?      bool     as t   -> Val.Constant t |> As<Val<string>>
| :?      Doc      as t   -> Val.Constant t |> As<Val<string>>
| :? Val< string>  as v   ->              v
| :? Var< string>  as v   -> Val.DynamicV v
| v when JS.In "RSet" v   -> Val.DynamicV (As<IRef<string>> v)
| :? Function      as vw  -> Val.Dynamic  (As<View<string>> vw)
| _                       -> failwith <| sprintf "Could not convert %A" o

[< Direct "$f($v)" >]
let inline fixitF f v = HelperType &> v
let inline fixit    v = fixitF toVal v
By on 10/18/2017 5:26 AM ()
By on 10/18/2017 6:43 AM ()

This is seriously cool, impressive and clever.

By on 10/17/2017 2:46 PM ()

I'm glad you like it. You probably also noticed I combine Tags, Attributes & Texts in a single Seq which is the only input to each tag. That makes it easier to read but it is also is easier to add more children (attributes, elements or events) when necessary .

By on 10/18/2017 6:28 AM ()