Work with Resource Description Framework (RDF) data in Elm. Use this package to convert Elm values into RDF graphs or vice versa, and build SPARQL queries.
Say we have some data about Alice, Bob and the Mona Lisa. With this package we can parse its Turtle serialization and decode everything into Elm values.
module Data exposing (persons)
import Rdf exposing (Iri)
import Rdf.Decode as Decode exposing (Decoder)
import Rdf.Graph as Graph
import Time
-- Start with the RDF graph in Turtle
data : String
data =
"""
@base <http://example.org/> .
@prefix dbpedia: <http://dbpedia.org/resource/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix schema: <http://schema.org/> .
@prefix terms: <http://purl.org/dc/terms/> .
@prefix wikidata: <http://www.wikidata.org/entity/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<bob#me> a foaf:Person ;
foaf:knows <alice#me> ;
schema:birthDate "1990-07-04"^^xsd:date ;
foaf:topic_interest wikidata:Q12418 .
wikidata:Q12418
terms:title "Mona Lisa" ;
terms:creator dbpedia:Leonardo_da_Vinci .
<http://data.europeana.eu/item/04802/243FA8618938F4117025F17A8B813C5F9AA4D619>
terms:subject wikidata:Q12418 .
"""
-- Define Elm types to model the data
type alias Person =
{ iri : Iri
, knows : List Iri
, birthDate : Time.Posix
, topic_interest : Topic
}
type alias Topic =
{ iri : Iri
, title : String
, creator : Iri
, subjectOf : List Iri
}
-- Write a decoder
decoder : Decoder (List Person)
decoder =
Decode.from (foaf "Person")
(Decode.property (Rdf.inverse Rdf.a)
(Decode.many decoderPerson)
)
decoderPerson : Decoder Person
decoderPerson =
Decode.succeed Person
|> Decode.custom Decode.iri
|> Decode.required (foaf "knows") (Decode.many Decode.iri)
|> Decode.required (schema "birthDate") Decode.date
|> Decode.required (foaf "topic_interest") decoderTopic
decoderTopic : Decoder Topic
decoderTopic =
Decode.succeed Topic
|> Decode.custom Decode.iri
|> Decode.required (terms "title") Decode.string
|> Decode.required (terms "creator") Decode.iri
|> Decode.required (Rdf.inverse (terms "subject"))
(Decode.many Decode.iri)
-- Finally, parse the RDF graph and
-- run the decoder to extract the data
persons : Result Decode.Error (List Person)
persons =
data
|> Graph.fromTurtle Rdf.initialSeed
|> Result.map Tuple.first
|> Result.withDefault Graph.empty
|> Graph.decode
(Decode.from (foaf "Person")
(Decode.property (Rdf.inverse Rdf.a)
(Decode.many decoder)
)
)
--> Ok
--> [ { iri = example "bob"
--> , knows = [ example "alice" ]
--> , birthDate = Time.millisToPosix 647049600000
--> , topic_interest =
--> { iri = wikidata "Q12418"
--> , title = "Mona Lisa"
--> , creator = dbpedia "Leonardo_da_Vinci"
--> , subjectOf = [ Rdf.iri "http://data.europeana.eu/item/04802/243FA8618938F4117025F17A8B813C5F9AA4D619" ]
--> }
--> }
--> ]
dbpedia : String -> Iri
dbpedia name =
Rdf.iri ("http://dbpedia.org/resource/" ++ name)
foaf : String -> Iri
foaf name =
Rdf.iri ("http://xmlns.com/foaf/0.1/" ++ name)
schema : String -> Iri
schema name =
Rdf.iri ("http://schema.org/" ++ name)
terms : String -> Iri
terms name =
Rdf.iri ("http://purl.org/dc/terms/" ++ name)
wikidata : String -> Iri
wikidata name =
Rdf.iri ("http://www.wikidata.org/entity/" ++ name)We don't consider this package to be feature complete. It is being actively developed as part of the semantic electronic lab notebook and research database Herbie. Currently, the following things are supported:
Iri, BlankNode, Literal, ...),
graphs (Graph), and datasets (Dataset).Graph's and Elm values via
elm-json-style
decoders and encoders.Here is an incomplete and unprioritized list of additional things which could go in this package:
And here is a list of other interesting topics concerning RDF and Elm, which could go into separate packages:
If you want to contribute, please reach out to us at [email protected]. You can open issues or merge requests on https://codebase.helmholtz.cloud/hereon-mb/elm-rdf.
Copyright 2024-2026 Helmholtz-Zentrum hereon GmbH
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this package except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.