В качестве побочного проекта я пытаюсь реализовать основы библиотеки RDF в OCaml.
Как вы можете (или не можете знать), оператор RDF (или тройной) состоит из 3 частей:
- субъект может быть IRI или пустым узлом;
- Предикат должен быть IRI;
- Объект может быть IRI, пустым узлом или литералом.
У меня есть модуль и типы для IRI, пустых узлов и литералов, и для проверки правил, описанных выше, вот что я начал писать:
(* In `triple.ml` *)
type subject = Iri of Iri.t | Bnode of Bnode.t
type objekt = Iri of Iri.t | Bnode of Bnode.t | Literal of Literal.t
type t = subject * Iri.t * objekt
let create s p o = s, p, o
Так что это хорошо и все, но одна вещь не дает мне покоя: всякий раз, когда я хочу использовать Triple.create
, я должен явно указать конструктор варианта:
let iri = (* Some Iri.t value *) in
let literal = (* Literal.t value *) in
Triple.create (Iri iri) iri (Literal literal)
Я почти уверен, что у OCaml есть способы обойти это, но я не уверен, как.
Некоторые мысли: я мог бы параметризовать тип Triple.t
с типом его субъекта и типом его объекта, но тогда как мне применить ограничения на типы параметров? Или, может быть, это хороший пример использования GADT?