От: | eao197 | http://eao197.blogspot.com | |
Дата: | 01.11.07 11:37 | ||
Оценка: | 47 (6) |
I make full usage of the OCaml type system to encode schema information in the types. I'm using phantom types, existential types (encoded using polymorphic records, rank-1 polymorphism), polymorphic variant types, structural polymorphism, (obviously) parametric polymorphism... But all the magic is encapsulated and none of it is seen by the developer; all you see is queries expressed in a simple language that are checked by the compiler. Fortunately, OCaml includes a tool that allows you to extend the language itself, camlp4. I have written a camlp4 extension that supports relational queries expressed like this:
(* this function takes a relation with a user_age attribute and returns another with the rows satisfying the predicate *) let minors users = SELECT [Age < 18] users
The "minors" function only makes sense when the relation given in the user argument has got an "age" attribute. This is encoded in the inferred type as follows:
val minors : ([> `Age of int ] as 'a, [> `Age ] as 'b) Relational.relation -> ('a, 'b) Relational.relation