This library contains F# generative type providers for RDF and SPARQL. It is built on top of dotNetRDF.
GraphProvider generates types from a schema or from a sample.
Given the following Turtle file alice.ttl:
@prefix : <http://example.org/> .
:alice a :Person ;
:age :42 .
The type provider infers a type Person
with a property Age
and a Get
factory method returning the instances in a given graph.
open Iride
open VDS.RDF
type G = GraphProvider<"alice.ttl">
let graph = new Graph()
Parsing.FileLoader.Load(graph, "alice.ttl")
let p = G.Person.Get(graph) |> Seq.exactlyOne
p.Age
|> Seq.exactlyOne
|> printfn "%i"
All properties are generated as sequences since RDF allows multiple values.
The same model is obtained using a schema (either RDFS or schema.org):
type G = GraphProvider<Schema = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <http://example.org/> .
:age rdfs:domain :Person ;
rdfs:range xsd:integer .
""">
SparqlQueryProvider checks SPARQL queries at design time, in the same vein as SqlCommandProvider. For example it detects syntax errors in SPARQL text:
It also provides typed input parameters and (for SELECT queries) typed Result
objects.
In the following example the type provider generates a type Q
with a static method GetText
and inner type Q.Result
.
The former allows to set input parameters (replacing $INT with 42 in the example).
The latter is a typed wrapper of SparqlResult
objects, with properties corresponding to
the output variables (s
and IRI_p
in the example) of the query.
open Iride
type Q = SparqlQueryProvider<"SELECT * WHERE { ?s ?IRI_p $INT }">
let exec: string -> VDS.RDF.Query.SparqlResultSet =
failwith "Use your favourite SPARQL client"
let query = Q.GetText(INT=42)
for r in exec(query) do
let result = Q.Result(r)
let subject: VDS.RDF.INode = result.s
let predicate: System.Uri = result.IRI_p
// ....
In SPARQL, output variables start with either '?' or '$' but, in practice, only '?' is used. Hence this library hijacks the prefix '$' to indicate input parameters.
Furthermore, upper case data type hints (e.g. IRI, INT) instruct the type provider to assign types to parameters and variables. Notice however that triple stores may return unparseable values due to the schemaless nature of RDF.
Supported data types are IRI, LIT, INT, NUM, DATE, TIME, BOOL.
SparqlCommandProvider behaves like SparqlQueryProvider except that it covers update commands.
type Cmd = SparqlCommandProvider<"""
INSERT DATA {$IRI_person <http://example.org/age> $INT_age}
""">
Cmd.GetText(
IRI_person = System.Uri "http://example.org/p1",
INT_age = 25)
|> printfn "%s"
// INSERT DATA {<http://example.org/p1> <http://example.org/age> 25 }
UriProvider creates System.Uri
properties from IRIs in RDF vocabularies.
type Book = UriProvider<"book.ttl">
let a: System.Uri = Book.author
The vocabulary can be either turtle text, a local file or a web resource. The list of IRIs for which a property is generated is obtained with the following SPARQL query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?uri ?label ?comment WHERE {
?uri rdfs:label ?label ;
rdfs:comment ?comment .
}
You can provide your own SPARQL query to customize the set of properties.
To detect typos in property and class names, it is useful to restrict the accepted vocabulary in queries and commands:
In the example above the type provider reports an error because BarZ is not present in the vocabulary specified by the Schema parameter.