hereon-mb/elm-rdf/1.1.2

NOTE: the latest version is 2.0.0

DOI pipeline status Latest Release

RDF in Elm

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.

Example

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.parse
        |> Result.withDefault Graph.emptyGraph
        |> Decode.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)

Features and future plans

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:

  • Parsing of Turtle and N-Triples files, and serialization into these formats.
  • Elm data model for RDF terms (Iri, BlankNode, Literal, ...) and graphs (Graph).
  • Conversion between Graph's and Elm values via elm-json-style decoders and encoders.
  • Combinators for building SPARQL queries.

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:

  • SHACL validator
  • SPARQL query engine

Contributing

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.

License information

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.