packages feed

rdf4h 1.0.2 → 1.1.0

raw patch · 16 files changed

+677/−628 lines, 16 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.RDF: BNode :: !Text -> Node
- Data.RDF: BNodeGen :: !Int -> Node
- Data.RDF: BaseUrl :: Text -> BaseUrl
- Data.RDF: LNode :: !LValue -> Node
- Data.RDF: ParseFailure :: String -> ParseFailure
- Data.RDF: PlainL :: !Text -> LValue
- Data.RDF: PlainLL :: !Text -> !Text -> LValue
- Data.RDF: PrefixMapping :: (Text, Text) -> PrefixMapping
- Data.RDF: PrefixMappings :: (Map Text Text) -> PrefixMappings
- Data.RDF: Triple :: !Node -> !Node -> !Node -> Triple
- Data.RDF: TypedL :: !Text -> !Text -> LValue
- Data.RDF: UNode :: !Text -> Node
- Data.RDF: addPrefixMappings :: RDF rdf => rdf -> PrefixMappings -> Bool -> rdf
- Data.RDF: baseUrl :: RDF rdf => rdf -> Maybe BaseUrl
- Data.RDF: bnode :: Text -> Node
- Data.RDF: class RDF rdf
- Data.RDF: class RdfParser p
- Data.RDF: class RdfSerializer s
- Data.RDF: class View a b
- Data.RDF: data LValue
- Data.RDF: data Node
- Data.RDF: data Triple
- Data.RDF: empty :: RDF rdf => rdf
- Data.RDF: equalObjects :: Triple -> Triple -> Bool
- Data.RDF: equalPredicates :: Triple -> Triple -> Bool
- Data.RDF: equalSubjects :: Triple -> Triple -> Bool
- Data.RDF: fromEither :: RDF rdf => Either ParseFailure rdf -> rdf
- Data.RDF: hWriteH :: (RdfSerializer s, RDF rdf) => s -> Handle -> rdf -> IO ()
- Data.RDF: hWriteN :: RdfSerializer s => s -> Handle -> Node -> IO ()
- Data.RDF: hWriteRdf :: (RdfSerializer s, RDF rdf) => s -> Handle -> rdf -> IO ()
- Data.RDF: hWriteT :: RdfSerializer s => s -> Handle -> Triple -> IO ()
- Data.RDF: hWriteTs :: RdfSerializer s => s -> Handle -> Triples -> IO ()
- Data.RDF: instance Eq BaseUrl
- Data.RDF: instance Eq LValue
- Data.RDF: instance Eq Node
- Data.RDF: instance Eq ParseFailure
- Data.RDF: instance Eq Triple
- Data.RDF: instance Ord BaseUrl
- Data.RDF: instance Ord LValue
- Data.RDF: instance Ord Node
- Data.RDF: instance Ord Triple
- Data.RDF: instance Show BaseUrl
- Data.RDF: instance Show LValue
- Data.RDF: instance Show Node
- Data.RDF: instance Show ParseFailure
- Data.RDF: instance Show Triple
- Data.RDF: isBNode :: Node -> Bool
- Data.RDF: isEmpty :: RDF rdf => rdf -> Bool
- Data.RDF: isIsomorphic :: (RDF rdf1, RDF rdf2) => rdf1 -> rdf2 -> Bool
- Data.RDF: isLNode :: Node -> Bool
- Data.RDF: isUNode :: Node -> Bool
- Data.RDF: listObjectsOfPredicate :: RDF rdf => rdf -> Predicate -> [Object]
- Data.RDF: listSubjectsWithPredicate :: RDF rdf => rdf -> Predicate -> [Subject]
- Data.RDF: lnode :: LValue -> Node
- Data.RDF: mkRdf :: RDF rdf => Triples -> Maybe BaseUrl -> PrefixMappings -> rdf
- Data.RDF: newtype BaseUrl
- Data.RDF: newtype ParseFailure
- Data.RDF: newtype PrefixMapping
- Data.RDF: newtype PrefixMappings
- Data.RDF: objectOf :: Triple -> Node
- Data.RDF: parseFile :: (RdfParser p, RDF rdf) => p -> String -> IO (Either ParseFailure rdf)
- Data.RDF: parseString :: (RdfParser p, RDF rdf) => p -> Text -> Either ParseFailure rdf
- Data.RDF: parseURL :: (RdfParser p, RDF rdf) => p -> String -> IO (Either ParseFailure rdf)
- Data.RDF: plainL :: Text -> LValue
- Data.RDF: plainLL :: Text -> Text -> LValue
- Data.RDF: predicateOf :: Triple -> Node
- Data.RDF: prefixMappings :: RDF rdf => rdf -> PrefixMappings
- Data.RDF: query :: RDF rdf => rdf -> Maybe Node -> Maybe Node -> Maybe Node -> Triples
- Data.RDF: rdfContainsNode :: RDF rdf => rdf -> Node -> Bool
- Data.RDF: removeDupes :: Triples -> Triples
- Data.RDF: s2t :: String -> Text
- Data.RDF: select :: RDF rdf => rdf -> NodeSelector -> NodeSelector -> NodeSelector -> Triples
- Data.RDF: sortTriples :: Triples -> Triples
- Data.RDF: subjectOf :: Triple -> Node
- Data.RDF: t2s :: Text -> String
- Data.RDF: toPMList :: PrefixMappings -> [(Text, Text)]
- Data.RDF: triple :: Subject -> Predicate -> Object -> Triple
- Data.RDF: tripleContainsNode :: Node -> Triple -> Bool
- Data.RDF: triplesOf :: RDF rdf => rdf -> Triples
- Data.RDF: type NodeSelector = Maybe (Node -> Bool)
- Data.RDF: type Object = Node
- Data.RDF: type Predicate = Node
- Data.RDF: type Subject = Node
- Data.RDF: type Triples = [Triple]
- Data.RDF: typedL :: Text -> Text -> LValue
- Data.RDF: unode :: Text -> Node
- Data.RDF: view :: View a b => a -> b
- Data.RDF: writeH :: (RdfSerializer s, RDF rdf) => s -> rdf -> IO ()
- Data.RDF: writeN :: RdfSerializer s => s -> Node -> IO ()
- Data.RDF: writeRdf :: (RdfSerializer s, RDF rdf) => s -> rdf -> IO ()
- Data.RDF: writeT :: RdfSerializer s => s -> Triple -> IO ()
- Data.RDF: writeTs :: RdfSerializer s => s -> Triples -> IO ()
- Data.RDF.Namespace: instance Eq Namespace
- Data.RDF.Namespace: instance Eq PrefixMapping
- Data.RDF.Namespace: instance Eq PrefixMappings
- Data.RDF.Namespace: instance Ord PrefixMapping
- Data.RDF.Namespace: instance Ord PrefixMappings
- Data.RDF.Namespace: instance Show Namespace
- Data.RDF.Namespace: instance Show PrefixMapping
- Data.RDF.Namespace: instance Show PrefixMappings
+ Data.RDF.Query: equalObjects :: Triple -> Triple -> Bool
+ Data.RDF.Query: equalPredicates :: Triple -> Triple -> Bool
+ Data.RDF.Query: equalSubjects :: Triple -> Triple -> Bool
+ Data.RDF.Query: expandTriples :: RDF rdf => rdf -> Triples
+ Data.RDF.Query: fromEither :: RDF rdf => Either ParseFailure rdf -> rdf
+ Data.RDF.Query: isEmpty :: RDF rdf => rdf -> Bool
+ Data.RDF.Query: isIsomorphic :: (RDF rdf1, RDF rdf2) => rdf1 -> rdf2 -> Bool
+ Data.RDF.Query: listObjectsOfPredicate :: RDF rdf => rdf -> Predicate -> [Object]
+ Data.RDF.Query: listSubjectsWithPredicate :: RDF rdf => rdf -> Predicate -> [Subject]
+ Data.RDF.Query: objectOf :: Triple -> Node
+ Data.RDF.Query: predicateOf :: Triple -> Node
+ Data.RDF.Query: rdfContainsNode :: RDF rdf => rdf -> Node -> Bool
+ Data.RDF.Query: removeDupes :: Triples -> Triples
+ Data.RDF.Query: sortTriples :: Triples -> Triples
+ Data.RDF.Query: subjectOf :: Triple -> Node
+ Data.RDF.Query: tripleContainsNode :: Node -> Triple -> Bool
+ Data.RDF.Types: BNode :: !Text -> Node
+ Data.RDF.Types: BNodeGen :: !Int -> Node
+ Data.RDF.Types: BaseUrl :: Text -> BaseUrl
+ Data.RDF.Types: LNode :: !LValue -> Node
+ Data.RDF.Types: ParseFailure :: String -> ParseFailure
+ Data.RDF.Types: PlainL :: !Text -> LValue
+ Data.RDF.Types: PlainLL :: !Text -> !Text -> LValue
+ Data.RDF.Types: PlainNS :: Text -> Namespace
+ Data.RDF.Types: PrefixMapping :: (Text, Text) -> PrefixMapping
+ Data.RDF.Types: PrefixMappings :: (Map Text Text) -> PrefixMappings
+ Data.RDF.Types: PrefixedNS :: Text -> Text -> Namespace
+ Data.RDF.Types: Triple :: !Node -> !Node -> !Node -> Triple
+ Data.RDF.Types: TypedL :: !Text -> !Text -> LValue
+ Data.RDF.Types: UNode :: !Text -> Node
+ Data.RDF.Types: addPrefixMappings :: RDF rdf => rdf -> PrefixMappings -> Bool -> rdf
+ Data.RDF.Types: baseUrl :: RDF rdf => rdf -> Maybe BaseUrl
+ Data.RDF.Types: bnode :: Text -> Node
+ Data.RDF.Types: class RDF rdf
+ Data.RDF.Types: class RdfParser p
+ Data.RDF.Types: class RdfSerializer s
+ Data.RDF.Types: class View a b
+ Data.RDF.Types: data LValue
+ Data.RDF.Types: data Namespace
+ Data.RDF.Types: data Node
+ Data.RDF.Types: data Triple
+ Data.RDF.Types: empty :: RDF rdf => rdf
+ Data.RDF.Types: hWriteH :: (RdfSerializer s, RDF rdf) => s -> Handle -> rdf -> IO ()
+ Data.RDF.Types: hWriteN :: RdfSerializer s => s -> Handle -> Node -> IO ()
+ Data.RDF.Types: hWriteRdf :: (RdfSerializer s, RDF rdf) => s -> Handle -> rdf -> IO ()
+ Data.RDF.Types: hWriteT :: RdfSerializer s => s -> Handle -> Triple -> IO ()
+ Data.RDF.Types: hWriteTs :: RdfSerializer s => s -> Handle -> Triples -> IO ()
+ Data.RDF.Types: instance Eq BaseUrl
+ Data.RDF.Types: instance Eq LValue
+ Data.RDF.Types: instance Eq Namespace
+ Data.RDF.Types: instance Eq Node
+ Data.RDF.Types: instance Eq ParseFailure
+ Data.RDF.Types: instance Eq PrefixMapping
+ Data.RDF.Types: instance Eq PrefixMappings
+ Data.RDF.Types: instance Eq Triple
+ Data.RDF.Types: instance Ord BaseUrl
+ Data.RDF.Types: instance Ord LValue
+ Data.RDF.Types: instance Ord Node
+ Data.RDF.Types: instance Ord PrefixMapping
+ Data.RDF.Types: instance Ord PrefixMappings
+ Data.RDF.Types: instance Ord Triple
+ Data.RDF.Types: instance Show BaseUrl
+ Data.RDF.Types: instance Show LValue
+ Data.RDF.Types: instance Show Namespace
+ Data.RDF.Types: instance Show Node
+ Data.RDF.Types: instance Show ParseFailure
+ Data.RDF.Types: instance Show PrefixMapping
+ Data.RDF.Types: instance Show PrefixMappings
+ Data.RDF.Types: instance Show Triple
+ Data.RDF.Types: isBNode :: Node -> Bool
+ Data.RDF.Types: isLNode :: Node -> Bool
+ Data.RDF.Types: isUNode :: Node -> Bool
+ Data.RDF.Types: lnode :: LValue -> Node
+ Data.RDF.Types: mkRdf :: RDF rdf => Triples -> Maybe BaseUrl -> PrefixMappings -> rdf
+ Data.RDF.Types: newtype BaseUrl
+ Data.RDF.Types: newtype ParseFailure
+ Data.RDF.Types: newtype PrefixMapping
+ Data.RDF.Types: newtype PrefixMappings
+ Data.RDF.Types: parseFile :: (RdfParser p, RDF rdf) => p -> String -> IO (Either ParseFailure rdf)
+ Data.RDF.Types: parseString :: (RdfParser p, RDF rdf) => p -> Text -> Either ParseFailure rdf
+ Data.RDF.Types: parseURL :: (RdfParser p, RDF rdf) => p -> String -> IO (Either ParseFailure rdf)
+ Data.RDF.Types: plainL :: Text -> LValue
+ Data.RDF.Types: plainLL :: Text -> Text -> LValue
+ Data.RDF.Types: prefixMappings :: RDF rdf => rdf -> PrefixMappings
+ Data.RDF.Types: query :: RDF rdf => rdf -> Maybe Node -> Maybe Node -> Maybe Node -> Triples
+ Data.RDF.Types: select :: RDF rdf => rdf -> NodeSelector -> NodeSelector -> NodeSelector -> Triples
+ Data.RDF.Types: triple :: Subject -> Predicate -> Object -> Triple
+ Data.RDF.Types: triplesOf :: RDF rdf => rdf -> Triples
+ Data.RDF.Types: type NodeSelector = Maybe (Node -> Bool)
+ Data.RDF.Types: type Object = Node
+ Data.RDF.Types: type Predicate = Node
+ Data.RDF.Types: type Subject = Node
+ Data.RDF.Types: type Triples = [Triple]
+ Data.RDF.Types: typedL :: Text -> Text -> LValue
+ Data.RDF.Types: unode :: Text -> Node
+ Data.RDF.Types: view :: View a b => a -> b
+ Data.RDF.Types: writeH :: (RdfSerializer s, RDF rdf) => s -> rdf -> IO ()
+ Data.RDF.Types: writeN :: RdfSerializer s => s -> Node -> IO ()
+ Data.RDF.Types: writeRdf :: (RdfSerializer s, RDF rdf) => s -> rdf -> IO ()
+ Data.RDF.Types: writeT :: RdfSerializer s => s -> Triple -> IO ()
+ Data.RDF.Types: writeTs :: RdfSerializer s => s -> Triples -> IO ()

Files

rdf4h.cabal view
@@ -1,5 +1,5 @@ name:            rdf4h-version:         1.0.2+version:         1.1.0 synopsis:        A library for RDF processing in Haskell description:        'RDF for Haskell' is a library for working with RDF in Haskell.@@ -19,7 +19,7 @@ build-type:      Simple category:        RDF stability:       Experimental-tested-with:     GHC==7.4.1+tested-with:     GHC==7.6.1 extra-tmp-files: test  flag small_base@@ -37,6 +37,8 @@ library   exposed-modules: Data.RDF                  , Data.RDF.Namespace+                 , Data.RDF.Types+                 , Data.RDF.Query                  , Data.RDF.MGraph                  , Data.RDF.TriplesGraph                  , Text.RDF.RDF4H.TurtleParser
src/Data/RDF.hs view
@@ -1,545 +1,31 @@--- |The Core module provides the fundamental types,--- type classes, and functions of the library.------- TODO: update writeT to writeTriple, etc.+-- |The Core module exports all serializers and parsers,+--  types, and query functions of the library.  module Data.RDF (-  -- * Parsing RDF-  RdfParser(parseString, parseFile, parseURL),-  -- * Serializing RDF-  RdfSerializer(hWriteRdf, writeRdf, hWriteH, writeH, hWriteTs, writeTs, hWriteT, writeT, hWriteN, writeN),-  -- * RDF type-  RDF(empty, mkRdf, triplesOf, select, query, baseUrl, prefixMappings, addPrefixMappings),-  -- * RDF triples, nodes, and literals-  Triple(Triple), triple, Triples, sortTriples,-  Node(UNode, BNode, BNodeGen, LNode),-  LValue(PlainL, PlainLL, TypedL), -  -- * Supporting types and functions-  BaseUrl(BaseUrl),-  PrefixMappings(PrefixMappings), toPMList, PrefixMapping(PrefixMapping),-  NodeSelector, isUNode, isBNode, isLNode,-  equalSubjects, equalPredicates, equalObjects,-  isIsomorphic,-  subjectOf, predicateOf, objectOf, isEmpty,-  rdfContainsNode,tripleContainsNode,-  listSubjectsWithPredicate,listObjectsOfPredicate,-  Subject, Predicate, Object,-  ParseFailure(ParseFailure),-  {- FastString(uniq,value),mkFastString, -}-  s2t,t2s,unode,bnode,lnode,plainL,plainLL,typedL,-  View, view,-  fromEither, removeDupes-)-where--import Data.RDF.Namespace-import Data.RDF.Utils ( s2t, t2s, canonicalize )-import qualified Data.Text as T-import Data.List-import System.IO-import Text.Printf---- |A type class for ADTs that expose views to clients.-class View a b where-  view :: a -> b---- |An alias for 'Node', defined for convenience and readability purposes.-type Subject = Node---- |An alias for 'Node', defined for convenience and readability purposes.-type Predicate = Node---- |An alias for 'Node', defined for convenience and readability purposes.-type Object = Node---- |An RDF value is a set of (unique) RDF triples, together with the--- operations defined upon them.------ For information about the efficiency of the functions, see the--- documentation for the particular RDF instance.------ For more information about the concept of an RDF graph, see--- the following: <http://www.w3.org/TR/rdf-concepts/#section-rdf-graph>.-class RDF rdf where--  -- |Return the base URL of this RDF, if any.-  baseUrl :: rdf -> Maybe BaseUrl--  -- |Return the prefix mappings defined for this RDF, if any.-  prefixMappings :: rdf -> PrefixMappings--  -- |Return an RDF with the specified prefix mappings merged with-  -- the existing mappings. If the Bool arg is True, then a new mapping-  -- for an existing prefix will replace the old mapping; otherwise,-  -- the new mapping is ignored.-  addPrefixMappings :: rdf -> PrefixMappings -> Bool -> rdf--  -- |Return an empty RDF.-  empty  :: rdf--  -- |Return a RDF containing all the given triples. Handling of duplicates-  -- in the input depend on the particular RDF implementation.-  mkRdf :: Triples -> Maybe BaseUrl -> PrefixMappings -> rdf--  -- |Return all triples in the RDF, as a list.-  triplesOf :: rdf -> Triples--  -- |Select the triples in the RDF that match the given selectors.-  ---  -- The three NodeSelector parameters are optional functions that match-  -- the respective subject, predicate, and object of a triple. The triples-  -- returned are those in the given graph for which the first selector-  -- returns true when called on the subject, the second selector returns-  -- true when called on the predicate, and the third selector returns true-  -- when called on the ojbect. A 'Nothing' parameter is equivalent to a-  -- function that always returns true for the appropriate node; but-  -- implementations may be able to much more efficiently answer a select-  -- that involves a 'Nothing' parameter rather than an @(id True)@ parameter.-  ---  -- The following call illustrates the use of select, and would result in-  -- the selection of all and only the triples that have a blank node-  -- as subject and a literal node as object:-  ---  -- > select gr (Just isBNode) Nothing (Just isLNode)-  ---  -- Note: this function may be very slow; see the documentation for the-  -- particular RDF implementation for more information.-  select    :: rdf -> NodeSelector -> NodeSelector -> NodeSelector -> Triples--  -- |Return the triples in the RDF that match the given pattern, where-  -- the pattern (3 Maybe Node parameters) is interpreted as a triple pattern.-  ---  -- The @Maybe Node@ params are interpreted as the subject, predicate, and-  -- object of a triple, respectively. @Just n@ is true iff the triple has-  -- a node equal to @n@ in the appropriate location; @Nothing@ is always-  -- true, regardless of the node in the appropriate location.-  ---  -- For example, @ query rdf (Just n1) Nothing (Just n2) @ would return all-  -- and only the triples that have @n1@ as subject and @n2@ as object,-  -- regardless of the predicate of the triple.-  query         :: rdf -> Maybe Node -> Maybe Node -> Maybe Node -> Triples---- |An RdfParser is a parser that knows how to parse 1 format of RDF and--- can parse an RDF document of that type from a string, a file, or a URL.--- Required configuration options will vary from instance to instance.-class RdfParser p where--  -- |Parse RDF from the given bytestring, yielding a failure with error message or-  -- the resultant RDF.-  parseString :: forall rdf. (RDF rdf) => p -> T.Text -> Either ParseFailure rdf--  -- |Parse RDF from the local file with the given path, yielding a failure with error-  -- message or the resultant RDF in the IO monad.-  parseFile   :: forall rdf. (RDF rdf) => p -> String     -> IO (Either ParseFailure rdf)--  -- |Parse RDF from the remote file with the given HTTP URL (https is not supported),-  -- yielding a failure with error message or the resultant graph in the IO monad.-  parseURL    :: forall rdf. (RDF rdf) => p -> String -> IO (Either ParseFailure rdf)---- |An RdfSerializer is a serializer of RDF to some particular output format, such as--- NTriples or Turtle.-class RdfSerializer s where-  -- |Write the RDF to a file handle using whatever configuration is specified by-  -- the first argument.-  hWriteRdf     :: forall rdf. (RDF rdf) => s -> Handle -> rdf -> IO ()--  -- |Write the RDF to stdout; equivalent to @'hWriteRdf' stdout@.-  writeRdf      :: forall rdf. (RDF rdf) => s -> rdf -> IO ()--  -- |Write to the file handle whatever header information is required based on-  -- the output format. For example, if serializing to Turtle, this method would-  -- write the necessary \@prefix declarations and possibly a \@baseUrl declaration,-  -- whereas for NTriples, there is no header section at all, so this would be a no-op.-  hWriteH     :: forall rdf. (RDF rdf) => s -> Handle -> rdf -> IO ()--  -- |Write header information to stdout; equivalent to @'hWriteRdf' stdout@.-  writeH      :: forall rdf. (RDF rdf) => s -> rdf -> IO ()--  -- |Write some triples to a file handle using whatever configuration is specified-  -- by the first argument. -  -- -  -- WARNING: if the serialization format has header-level information -  -- that should be output (e.g., \@prefix declarations for Turtle), then you should-  -- use 'hWriteG' instead of this method unless you're sure this is safe to use, since-  -- otherwise the resultant document will be missing the header information and -  -- will not be valid.-  hWriteTs    :: s -> Handle  -> Triples -> IO ()--  -- |Write some triples to stdout; equivalent to @'hWriteTs' stdout@.-  writeTs     :: s -> Triples -> IO ()--  -- |Write a single triple to the file handle using whatever configuration is -  -- specified by the first argument. The same WARNING applies as to 'hWriteTs'.-  hWriteT     :: s -> Handle  -> Triple  -> IO ()--  -- |Write a single triple to stdout; equivalent to @'hWriteT' stdout@.-  writeT      :: s -> Triple  -> IO ()--  -- |Write a single node to the file handle using whatever configuration is -  -- specified by the first argument. The same WARNING applies as to 'hWriteTs'.-  hWriteN     :: s -> Handle  -> Node    -> IO ()--  -- |Write a single node to sdout; equivalent to @'hWriteN' stdout@.-  writeN      :: s -> Node    -> IO ()---- |An RDF node, which may be either a URIRef node ('UNode'), a blank--- node ('BNode'), or a literal node ('LNode').-data Node =--  -- |An RDF URI reference. See-  -- <http://www.w3.org/TR/rdf-concepts/#section-Graph-URIref> for more-  -- information.-  UNode !T.Text--  -- |An RDF blank node. See-  -- <http://www.w3.org/TR/rdf-concepts/#section-blank-nodes> for more-  -- information.-  | BNode !T.Text--  -- |An RDF blank node with an auto-generated identifier, as used in-  -- Turtle.-  | BNodeGen !Int--  -- |An RDF literal. See-  -- <http://www.w3.org/TR/rdf-concepts/#section-Graph-Literal> for more-  -- information.-  | LNode !LValue---- ==============================--- Constructor functions for Node---- |Return a URIRef node for the given bytetring URI.-{-# INLINE unode #-}-unode :: T.Text -> Node-unode = UNode---- |Return a blank node using the given string identifier.-{-# INLINE bnode #-}-bnode :: T.Text ->  Node-bnode = BNode---- |Return a literal node using the given LValue.-{-# INLINE lnode #-}-lnode :: LValue ->  Node-lnode = LNode---- Constructor functions for Node--- ==============================----- |A list of triples. This is defined for convenience and readability.-type Triples = [Triple]---- |An RDF triple is a statement consisting of a subject, predicate,--- and object, respectively.------ See <http://www.w3.org/TR/rdf-concepts/#section-triples> for--- more information.-data Triple = Triple !Node !Node !Node---- |A smart constructor function for 'Triple' that verifies the node arguments--- are of the correct type and creates the new 'Triple' if so or calls 'error'.--- /subj/ must be a 'UNode' or 'BNode', and /pred/ must be a 'UNode'.-triple :: Subject -> Predicate -> Object -> Triple-triple subj pred obj-  | isLNode subj     =  error $ "subject must be UNode or BNode: "     ++ show subj-  | isLNode pred     =  error $ "predicate must be UNode, not LNode: " ++ show pred-  | isBNode pred     =  error $ "predicate must be UNode, not BNode: " ++ show pred-  | otherwise        =  Triple subj pred obj---- |The actual value of an RDF literal, represented as the 'LValue'--- parameter of an 'LNode'.-data LValue =-  -- Constructors are not exported, because we need to have more-  -- control over the format of the literal bytestring that we store.--  -- |A plain (untyped) literal value in an unspecified language.-  PlainL !T.Text--  -- |A plain (untyped) literal value with a language specifier.-  | PlainLL !T.Text !T.Text--  -- |A typed literal value consisting of the literal value and-  -- the URI of the datatype of the value, respectively.-  | TypedL !T.Text  !T.Text---- ================================--- Constructor functions for LValue---- |Return a PlainL LValue for the given string value.-{-# INLINE plainL #-}-plainL :: T.Text -> LValue-plainL =  PlainL---- |Return a PlainLL LValue for the given string value and language,--- respectively.-{-# INLINE plainLL #-}-plainLL :: T.Text -> T.Text -> LValue-plainLL = PlainLL---- |Return a TypedL LValue for the given string value and datatype URI,--- respectively.-{-# INLINE typedL #-}-typedL :: T.Text -> T.Text -> LValue-typedL val dtype = TypedL (canonicalize dtype val) dtype---- Constructor functions for LValue--- ================================----- |The base URL of an RDF.-newtype BaseUrl = BaseUrl T.Text-  deriving (Eq, Ord, Show)---- |A 'NodeSelector' is either a function that returns 'True'---  or 'False' for a node, or Nothing, which indicates that all--- nodes would return 'True'.------ The selector is said to select, or match, the nodes for--- which it returns 'True'.------ When used in conjunction with the 'select' method of 'Graph', three--- node selectors are used to match a triple.-type NodeSelector = Maybe (Node -> Bool)---- |Represents a failure in parsing an N-Triples document, including--- an error message with information about the cause for the failure.-newtype ParseFailure = ParseFailure String-  deriving (Eq, Show)---- |A node is equal to another node if they are both the same type--- of node and if the field values are equal.-instance Eq Node where-  (UNode bs1)    ==  (UNode bs2)     =   bs1 ==  bs2-  (BNode bs1)    ==  (BNode bs2)     =   bs1 ==  bs2-  (BNodeGen i1)  ==  (BNodeGen i2)   =  i1 == i2-  (LNode l1)     ==  (LNode l2)      =  l1 == l2-  _              ==  _               =  False---- |Node ordering is defined first by type, with Unode < BNode < BNodeGen--- < LNode PlainL < LNode PlainLL < LNode TypedL, and secondly by--- the natural ordering of the node value.------ E.g., a '(UNode _)' is LT any other type of node, and a--- '(LNode (TypedL _ _))' is GT any other type of node, and the ordering--- of '(BNodeGen 44)' and '(BNodeGen 3)' is that of the values, or--- 'compare 44 3', GT.-instance Ord Node where-  compare = compareNode--compareNode :: Node -> Node -> Ordering-compareNode (UNode bs1)                      (UNode bs2)                      = compare bs1 bs2-compareNode (UNode _)                        _                                = LT-compareNode (BNode bs1)                      (BNode bs2)                      = compare bs1 bs2-compareNode (BNode _)                        (UNode _)                        = GT-compareNode (BNode _)                        _                                = LT-compareNode (BNodeGen i1)                    (BNodeGen i2)                    = compare i1 i2-compareNode (BNodeGen _)                     (LNode _)                        = LT-compareNode (BNodeGen _)                     _                                = GT-compareNode (LNode (PlainL bs1))             (LNode (PlainL bs2))             = compare bs1 bs2-compareNode (LNode (PlainL _))               (LNode _)                        = LT-compareNode (LNode (PlainLL bs1 bs1'))       (LNode (PlainLL bs2 bs2'))       =-  case compare bs1' bs2' of-    EQ -> compare bs1 bs2-    LT -> LT-    GT -> GT-compareNode (LNode (PlainLL _ _))            (LNode (PlainL _))               = GT-compareNode (LNode (PlainLL _ _))            (LNode _)                        = LT-compareNode (LNode (TypedL bsType1 bs1))         (LNode (TypedL bsType2 bs2))         =-  case compare bs1 bs2 of-    EQ -> compare bsType1 bsType2-    LT -> LT-    GT -> GT-compareNode (LNode (TypedL _ _))             (LNode _)                        = GT-compareNode (LNode _)                        _                                = GT---- |Two triples are equal iff their respective subjects, predicates, and objects--- are equal.-instance Eq Triple where-  (Triple s1 p1 o1) == (Triple s2 p2 o2) = s1 == s2 && p1 == p2 && o1 == o2---- |The ordering of triples is based on that of the subject, predicate, and object--- of the triple, in that order.-instance Ord Triple where-  (Triple s1 p1 o1) `compare` (Triple s2 p2 o2) =-    case compareNode s1 s2 of-      EQ -> case compareNode p1 p2 of-              EQ -> compareNode o1 o2-              LT -> LT-              GT -> GT-      GT -> GT-      LT -> LT---- |Two 'LValue' values are equal iff they are of the same type and all fields are--- equal.-instance Eq LValue where-  (PlainL bs1)        ==  (PlainL bs2)        =  bs1 == bs2-  (PlainLL bs1 bs1')  ==  (PlainLL bs2 bs2')  =  bs1' == bs2'    &&  bs1 == bs2-  (TypedL bsType1 bs1)    ==  (TypedL bsType2 bs2)    =  bsType1 == bsType2 &&  bs1 == bs2-  _                   ==  _                   =  False---- |Ordering of 'LValue' values is as follows: (PlainL _) < (PlainLL _ _)--- < (TypedL _ _), and values of the same type are ordered by field values,--- with '(PlainLL literalValue language)' being ordered by language first and--- literal value second, and '(TypedL literalValue datatypeUri)' being ordered--- by datatype first and literal value second.-instance Ord LValue where-  compare = compareLValue--{-# INLINE compareLValue #-}-compareLValue :: LValue -> LValue -> Ordering-compareLValue (PlainL bs1)       (PlainL bs2)       = compare bs1 bs2-compareLValue (PlainL _)         _                  = LT-compareLValue _                  (PlainL _)         = GT-compareLValue (PlainLL bs1 bs1') (PlainLL bs2 bs2') =-  case compare bs1' bs2' of-    EQ -> compare bs1 bs2-    GT -> GT-    LT -> LT-compareLValue (PlainLL _ _)       _                 = LT-compareLValue _                   (PlainLL _ _)     = GT-compareLValue (TypedL l1 t1) (TypedL l2 t2) =-  case compare t1 t2 of-    EQ -> compare l1 l2-    GT -> GT-    LT -> LT---- String representations of the various data types; generally NTriples-like.--instance Show Triple where-  show (Triple s p o) =-    printf "Triple(%s,%s,%s)" (show s) (show p) (show o)--instance Show Node where-  show (UNode uri)                   = "UNode(" ++ show uri ++ ")"-  show (BNode  i)                    = "BNode(" ++ show i ++ ")"-  show (BNodeGen genId)              = "BNodeGen(" ++ show genId ++ ")"-  show (LNode lvalue)                = "LNode(" ++ show lvalue ++ ")"--instance Show LValue where-  show (PlainL lit)               = "PlainL(" ++ T.unpack lit ++ ")"-  show (PlainLL lit lang)         = "PlainLL(" ++ T.unpack lit ++ ", " ++ T.unpack lang ++ ")"-  show (TypedL lit dtype)         = "TypedL(" ++ T.unpack lit ++ "," ++ show dtype ++ ")"---- |Answer the given list of triples in sorted order.-sortTriples :: Triples -> Triples-sortTriples = sort---- |Answer the subject node of the triple.-{-# INLINE subjectOf #-}-subjectOf :: Triple -> Node-subjectOf (Triple s _ _) = s---- |Answer the predicate node of the triple.-{-# INLINE predicateOf #-}-predicateOf :: Triple -> Node-predicateOf (Triple _ p _) = p---- |Answer the object node of the triple.-{-# INLINE objectOf #-}-objectOf :: Triple -> Node-objectOf (Triple _ _ o)   = o---- |Answer if rdf contains node.-rdfContainsNode :: forall rdf. (RDF rdf) => rdf -> Node -> Bool-rdfContainsNode rdf node =-  let ts = triplesOf rdf-      xs = map (tripleContainsNode node) ts-  in elem True xs---- |Answer if triple contains node.-tripleContainsNode :: Node -> Triple -> Bool-{-# INLINE tripleContainsNode #-}-tripleContainsNode node t = - subjectOf t == node || predicateOf t == node || objectOf t == node---- |Answer if given node is a URI Ref node.-{-# INLINE isUNode #-}-isUNode :: Node -> Bool-isUNode (UNode _) = True-isUNode _         = False---- |Answer if given node is a blank node.-{-# INLINE isBNode #-}-isBNode :: Node -> Bool-isBNode (BNode _)    = True-isBNode (BNodeGen _) = True-isBNode _            = False---- |Answer if given node is a literal node.-{-# INLINE isLNode #-}-isLNode :: Node -> Bool-isLNode (LNode _) = True-isLNode _         = False---- |Determine whether two triples have equal subjects.-equalSubjects :: Triple -> Triple -> Bool-equalSubjects (Triple s1 _ _) (Triple s2 _ _) = s1 == s2---- |Determine whether two triples have equal predicates.-equalPredicates :: Triple -> Triple -> Bool-equalPredicates (Triple _ p1 _) (Triple _ p2 _) = p1 == p2---- |Determine whether two triples have equal objects.-equalObjects :: Triple -> Triple -> Bool-equalObjects (Triple _ _ o1) (Triple _ _ o2) = o1 == o2---- |Determines whether the 'RDF' contains zero triples.-isEmpty :: RDF rdf => rdf -> Bool-isEmpty rdf =-  let ts = triplesOf rdf-  in null ts---- |Lists of all subjects of triples with the given predicate.-listSubjectsWithPredicate :: RDF rdf => rdf -> Predicate -> [Subject]-listSubjectsWithPredicate rdf pred =-  listNodesWithPredicate rdf pred subjectOf---- |Lists of all objects of triples with the given predicate.-listObjectsOfPredicate :: RDF rdf => rdf -> Predicate -> [Object]-listObjectsOfPredicate rdf pred =-  listNodesWithPredicate rdf pred objectOf--listNodesWithPredicate :: RDF rdf => rdf -> Predicate -> (Triple -> Node) -> [Node]-listNodesWithPredicate rdf pred f =-  let ts = triplesOf rdf-      xs = filter (\t -> predicateOf t == pred) ts-  in map f xs----- |Convert a parse result into an RDF if it was successful--- and error and terminate if not.-fromEither :: RDF rdf => Either ParseFailure rdf -> rdf-fromEither res =-  case res of-    (Left err) -> error (show err)-    (Right rdf) -> rdf+  -- * Export types and query functions+  module Data.RDF.Types,+  module Data.RDF.Query, --- |Remove duplicate triples, returning unique triples. This --- function may return the triples in a different order than --- given.-removeDupes :: Triples -> Triples-removeDupes =  map head . group . sort+  -- * Export RDF type class instances+  module Data.RDF.TriplesGraph,+  module Data.RDF.MGraph, --- |This determines if two RDF representations are equal regardless of blank--- node names, triple order and prefixes.  In math terms, this is the \simeq--- latex operator, or ~=-isIsomorphic :: forall rdf1 rdf2. (RDF rdf1, RDF rdf2) => rdf1 -> rdf2 -> Bool-isIsomorphic g1 g2 = normalize g1 == normalize g2-  where normalize :: forall rdf. (RDF rdf) => rdf -> Triples-        normalize = sort . nub . expandTriples+  -- * Export RDF parsers and serializers+  module Text.RDF.RDF4H.NTriplesSerializer,+  module Text.RDF.RDF4H.NTriplesParser,+  module Text.RDF.RDF4H.TurtleSerializer,+  module Text.RDF.RDF4H.TurtleParser, --- |Expand the triples in a graph with the prefix map and base URL for that--- graph.-expandTriples :: (RDF rdf) => rdf -> Triples-expandTriples rdf = expandTriples' [] (baseUrl rdf) (prefixMappings rdf) (triplesOf rdf)+)+where -expandTriples' :: Triples -> Maybe BaseUrl -> PrefixMappings -> Triples -> Triples-expandTriples' acc _ _ [] = acc-expandTriples' acc baseUrl prefixMappings (t:rest) = expandTriples' (normalize baseUrl prefixMappings t : acc) baseUrl prefixMappings rest-  where normalize baseUrl prefixMappings = expandPrefixes prefixMappings . expandBaseUrl baseUrl-        expandBaseUrl (Just _) triple = triple-        expandBaseUrl Nothing triple = triple-        expandPrefixes _ triple = triple+import Data.RDF.Namespace+import Data.RDF.TriplesGraph+import Data.RDF.MGraph+import Text.RDF.RDF4H.NTriplesSerializer+import Text.RDF.RDF4H.TurtleSerializer+import Text.RDF.RDF4H.NTriplesParser+import Text.RDF.RDF4H.TurtleParser+import Data.RDF.Types+import Data.RDF.Query
src/Data/RDF/MGraph.hs view
@@ -4,7 +4,8 @@  where -import Data.RDF+import Data.RDF.Types+import Data.RDF.Query import Data.RDF.Namespace import Data.Map(Map) import qualified Data.Map as Map
src/Data/RDF/Namespace.hs view
@@ -15,11 +15,9 @@ ) where -import Text.Printf-import Data.Map(Map)-import qualified Data.Map as Map-import qualified Data.List as List import qualified Data.Text as T+import Data.RDF.Types+import qualified Data.Map as Map  standard_namespaces :: [Namespace] standard_namespaces = [rdf, rdfs, dc, dct, owl, xsd, skos, foaf, ex, ex2]@@ -73,15 +71,6 @@ ex2  :: Namespace ex2   =   mkPrefixedNS'  "ex2"   "http://www2.example.org/" --- |An alias for a map from prefix to namespace URI.-newtype PrefixMappings   = PrefixMappings (Map T.Text T.Text)-  deriving (Eq, Ord)-instance Show PrefixMappings where-  -- This is really inefficient, but it's not used much so not what-  -- worth optimizing yet.-  show (PrefixMappings pmap) = printf "PrefixMappings [%s]" mappingsStr-    where showPM      = show . PrefixMapping-          mappingsStr = List.intercalate ", " (map showPM (Map.toList pmap))  -- |Perform a left-biased merge of the two sets of prefix mappings. mergePrefixMappings :: PrefixMappings -> PrefixMappings -> PrefixMappings@@ -93,20 +82,10 @@ toPMList :: PrefixMappings -> [(T.Text, T.Text)] toPMList (PrefixMappings m) = Map.toList m --- |A mapping of a prefix to the URI for that prefix.-newtype PrefixMapping = PrefixMapping (T.Text, T.Text)-  deriving (Eq, Ord)-instance Show PrefixMapping where-  show (PrefixMapping (prefix, uri)) = printf "PrefixMapping (%s, %s)" (show prefix) (show uri)- -- |Make a URI consisting of the given namespace and the given localname. mkUri :: Namespace -> T.Text -> T.Text mkUri ns local = uriOf ns `T.append` local --- |Represents a namespace as either a prefix and uri, respectively,---  or just a uri.-data Namespace = PrefixedNS  T.Text T.Text -- prefix and ns uri-               | PlainNS     T.Text            -- ns uri alone  -- |Make a namespace for the given URI reference. mkPlainNS     ::  T.Text -> Namespace@@ -122,16 +101,6 @@ -- automatically. mkPrefixedNS' :: String -> String -> Namespace mkPrefixedNS' s1 s2 = mkPrefixedNS (T.pack s1) (T.pack s2)--instance Eq Namespace where-  (PrefixedNS _ u1) == (PrefixedNS _ u2)  = u1 == u2-  (PlainNS      u1) == (PlainNS      u2)  = u1 == u2-  (PrefixedNS _ u1) == (PlainNS      u2)  = u1 == u2-  (PlainNS      u1) == (PrefixedNS _ u2)  = u1 == u2--instance Show Namespace where-  show (PlainNS           uri)  =  T.unpack uri-  show (PrefixedNS prefix uri)  =  printf "(PrefixNS %s %s)" (T.unpack prefix) (T.unpack uri)  -- |Determine the URI of the given namespace. uriOf     ::  Namespace -> T.Text
+ src/Data/RDF/Query.hs view
@@ -0,0 +1,118 @@++module Data.RDF.Query (++  -- * Query functions+  sortTriples, equalSubjects, equalPredicates, equalObjects,+  subjectOf, predicateOf, objectOf, isEmpty,+  rdfContainsNode, tripleContainsNode, removeDupes,+  listSubjectsWithPredicate, listObjectsOfPredicate,++  -- * RDF graph functions+  isIsomorphic, expandTriples, fromEither++) where++import Data.RDF.Types+import Data.List++-- |Answer the given list of triples in sorted order.+sortTriples :: Triples -> Triples+sortTriples = sort++-- |Answer the subject node of the triple.+{-# INLINE subjectOf #-}+subjectOf :: Triple -> Node+subjectOf (Triple s _ _) = s++-- |Answer the predicate node of the triple.+{-# INLINE predicateOf #-}+predicateOf :: Triple -> Node+predicateOf (Triple _ p _) = p++-- |Answer the object node of the triple.+{-# INLINE objectOf #-}+objectOf :: Triple -> Node+objectOf (Triple _ _ o)   = o++-- |Answer if rdf contains node.+rdfContainsNode :: forall rdf. (RDF rdf) => rdf -> Node -> Bool+rdfContainsNode rdf node =+  let ts = triplesOf rdf+      xs = map (tripleContainsNode node) ts+  in elem True xs++-- |Answer if triple contains node.+tripleContainsNode :: Node -> Triple -> Bool+{-# INLINE tripleContainsNode #-}+tripleContainsNode node t = + subjectOf t == node || predicateOf t == node || objectOf t == node+++-- |Determine whether two triples have equal subjects.+equalSubjects :: Triple -> Triple -> Bool+equalSubjects (Triple s1 _ _) (Triple s2 _ _) = s1 == s2++-- |Determine whether two triples have equal predicates.+equalPredicates :: Triple -> Triple -> Bool+equalPredicates (Triple _ p1 _) (Triple _ p2 _) = p1 == p2++-- |Determine whether two triples have equal objects.+equalObjects :: Triple -> Triple -> Bool+equalObjects (Triple _ _ o1) (Triple _ _ o2) = o1 == o2++-- |Determines whether the 'RDF' contains zero triples.+isEmpty :: RDF rdf => rdf -> Bool+isEmpty rdf =+  let ts = triplesOf rdf+  in null ts++-- |Lists of all subjects of triples with the given predicate.+listSubjectsWithPredicate :: RDF rdf => rdf -> Predicate -> [Subject]+listSubjectsWithPredicate rdf pred =+  listNodesWithPredicate rdf pred subjectOf++-- |Lists of all objects of triples with the given predicate.+listObjectsOfPredicate :: RDF rdf => rdf -> Predicate -> [Object]+listObjectsOfPredicate rdf pred =+  listNodesWithPredicate rdf pred objectOf++listNodesWithPredicate :: RDF rdf => rdf -> Predicate -> (Triple -> Node) -> [Node]+listNodesWithPredicate rdf pred f =+  let ts = triplesOf rdf+      xs = filter (\t -> predicateOf t == pred) ts+  in map f xs++-- |Convert a parse result into an RDF if it was successful+-- and error and terminate if not.+fromEither :: RDF rdf => Either ParseFailure rdf -> rdf+fromEither res =+  case res of+    (Left err) -> error (show err)+    (Right rdf) -> rdf++-- |Remove duplicate triples, returning unique triples. This +-- function may return the triples in a different order than +-- given.+removeDupes :: Triples -> Triples+removeDupes =  map head . group . sort++-- |This determines if two RDF representations are equal regardless of blank+-- node names, triple order and prefixes.  In math terms, this is the \simeq+-- latex operator, or ~=+isIsomorphic :: forall rdf1 rdf2. (RDF rdf1, RDF rdf2) => rdf1 -> rdf2 -> Bool+isIsomorphic g1 g2 = normalize g1 == normalize g2+  where normalize :: forall rdf. (RDF rdf) => rdf -> Triples+        normalize = sort . nub . expandTriples++-- |Expand the triples in a graph with the prefix map and base URL for that+-- graph.+expandTriples :: (RDF rdf) => rdf -> Triples+expandTriples rdf = expandTriples' [] (baseUrl rdf) (prefixMappings rdf) (triplesOf rdf)++expandTriples' :: Triples -> Maybe BaseUrl -> PrefixMappings -> Triples -> Triples+expandTriples' acc _ _ [] = acc+expandTriples' acc baseUrl prefixMappings (t:rest) = expandTriples' (normalize baseUrl prefixMappings t : acc) baseUrl prefixMappings rest+  where normalize baseUrl prefixMappings = expandPrefixes prefixMappings . expandBaseUrl baseUrl+        expandBaseUrl (Just _) triple = triple+        expandBaseUrl Nothing triple = triple+        expandPrefixes _ triple = triple
src/Data/RDF/TriplesGraph.hs view
@@ -12,7 +12,8 @@  where -import Data.RDF+import Data.RDF.Types+import Data.RDF.Query import Data.RDF.Namespace import qualified Data.Map as Map 
+ src/Data/RDF/Types.hs view
@@ -0,0 +1,511 @@++module Data.RDF.Types (++  -- * RDF triples, nodes and literals+  LValue(PlainL,PlainLL,TypedL),+  Node(UNode,BNode,BNodeGen,LNode), Subject, Predicate, Object,+  Triple(Triple), Triples, View(view),++  -- * Constructor functions+  plainL,plainLL,typedL,+  unode,bnode,lnode,triple,++  -- * Node query function+  isUNode,isLNode,isBNode,++  -- * RDF Type+  RDF(baseUrl,prefixMappings,addPrefixMappings,empty,mkRdf,triplesOf,select,query),++  -- * Parsing RDF+  RdfParser(parseString,parseFile,parseURL),++  -- * Serializing RDF+  RdfSerializer(hWriteRdf,writeRdf,hWriteH,writeH,hWriteTs,hWriteT,writeT, writeTs,hWriteN, writeN),++  -- * Namespaces and Prefixes+  Namespace(PrefixedNS,PlainNS),+  PrefixMappings(PrefixMappings),PrefixMapping(PrefixMapping),++  -- * Supporting types+  BaseUrl(BaseUrl), NodeSelector, ParseFailure(ParseFailure),++) where++import qualified Data.Text as T+import System.IO+import Text.Printf+import Data.Map(Map)+import qualified Data.List as List+import qualified Data.Map as Map++-------------------+-- LValue and constructor functions++-- |The actual value of an RDF literal, represented as the 'LValue'+-- parameter of an 'LNode'.+data LValue =+  -- Constructors are not exported, because we need to have more+  -- control over the format of the literal text that we store.++  -- |A plain (untyped) literal value in an unspecified language.+  PlainL !T.Text++  -- |A plain (untyped) literal value with a language specifier.+  | PlainLL !T.Text !T.Text++  -- |A typed literal value consisting of the literal value and+  -- the URI of the datatype of the value, respectively.+  | TypedL !T.Text  !T.Text++-- |Return a PlainL LValue for the given string value.+{-# INLINE plainL #-}+plainL :: T.Text -> LValue+plainL =  PlainL++-- |Return a PlainLL LValue for the given string value and language,+-- respectively.+{-# INLINE plainLL #-}+plainLL :: T.Text -> T.Text -> LValue+plainLL = PlainLL++-- |Return a TypedL LValue for the given string value and datatype URI,+-- respectively.+{-# INLINE typedL #-}+typedL :: T.Text -> T.Text -> LValue+typedL val dtype = TypedL (canonicalize dtype val) dtype++-------------------+-- Node and constructor functions++-- |An RDF node, which may be either a URIRef node ('UNode'), a blank+-- node ('BNode'), or a literal node ('LNode').+data Node =++  -- |An RDF URI reference. See+  -- <http://www.w3.org/TR/rdf-concepts/#section-Graph-URIref> for more+  -- information.+  UNode !T.Text++  -- |An RDF blank node. See+  -- <http://www.w3.org/TR/rdf-concepts/#section-blank-nodes> for more+  -- information.+  | BNode !T.Text++  -- |An RDF blank node with an auto-generated identifier, as used in+  -- Turtle.+  | BNodeGen !Int++  -- |An RDF literal. See+  -- <http://www.w3.org/TR/rdf-concepts/#section-Graph-Literal> for more+  -- information.+  | LNode !LValue++-- |An alias for 'Node', defined for convenience and readability purposes.+type Subject = Node++-- |An alias for 'Node', defined for convenience and readability purposes.+type Predicate = Node++-- |An alias for 'Node', defined for convenience and readability purposes.+type Object = Node++-- |Return a URIRef node for the given bytetring URI.+{-# INLINE unode #-}+unode :: T.Text -> Node+unode = UNode++-- |Return a blank node using the given string identifier.+{-# INLINE bnode #-}+bnode :: T.Text ->  Node+bnode = BNode++-- |Return a literal node using the given LValue.+{-# INLINE lnode #-}+lnode :: LValue ->  Node+lnode = LNode++-------------------+-- Triple and constructor functions++-- |An RDF triple is a statement consisting of a subject, predicate,+-- and object, respectively.+--+-- See <http://www.w3.org/TR/rdf-concepts/#section-triples> for+-- more information.+data Triple = Triple !Node !Node !Node++-- |A list of triples. This is defined for convenience and readability.+type Triples = [Triple]++-- |A smart constructor function for 'Triple' that verifies the node arguments+-- are of the correct type and creates the new 'Triple' if so or calls 'error'.+-- /subj/ must be a 'UNode' or 'BNode', and /pred/ must be a 'UNode'.+triple :: Subject -> Predicate -> Object -> Triple+triple subj pred obj+  | isLNode subj     =  error $ "subject must be UNode or BNode: "     ++ show subj+  | isLNode pred     =  error $ "predicate must be UNode, not LNode: " ++ show pred+  | isBNode pred     =  error $ "predicate must be UNode, not BNode: " ++ show pred+  | otherwise        =  Triple subj pred obj++-- |Answer if given node is a URI Ref node.+{-# INLINE isUNode #-}+isUNode :: Node -> Bool+isUNode (UNode _) = True+isUNode _         = False++-- |Answer if given node is a blank node.+{-# INLINE isBNode #-}+isBNode :: Node -> Bool+isBNode (BNode _)    = True+isBNode (BNodeGen _) = True+isBNode _            = False++-- |Answer if given node is a literal node.+{-# INLINE isLNode #-}+isLNode :: Node -> Bool+isLNode (LNode _) = True+isLNode _         = False++-- |A type class for ADTs that expose views to clients.+class View a b where+  view :: a -> b++-- |An RDF value is a set of (unique) RDF triples, together with the+-- operations defined upon them.+--+-- For information about the efficiency of the functions, see the+-- documentation for the particular RDF instance.+--+-- For more information about the concept of an RDF graph, see+-- the following: <http://www.w3.org/TR/rdf-concepts/#section-rdf-graph>.+class RDF rdf where++  -- |Return the base URL of this RDF, if any.+  baseUrl :: rdf -> Maybe BaseUrl++  -- |Return the prefix mappings defined for this RDF, if any.+  prefixMappings :: rdf -> PrefixMappings++  -- |Return an RDF with the specified prefix mappings merged with+  -- the existing mappings. If the Bool arg is True, then a new mapping+  -- for an existing prefix will replace the old mapping; otherwise,+  -- the new mapping is ignored.+  addPrefixMappings :: rdf -> PrefixMappings -> Bool -> rdf++  -- |Return an empty RDF.+  empty  :: rdf++  -- |Return a RDF containing all the given triples. Handling of duplicates+  -- in the input depend on the particular RDF implementation.+  mkRdf :: Triples -> Maybe BaseUrl -> PrefixMappings -> rdf++  -- |Return all triples in the RDF, as a list.+  triplesOf :: rdf -> Triples++  -- |Select the triples in the RDF that match the given selectors.+  --+  -- The three NodeSelector parameters are optional functions that match+  -- the respective subject, predicate, and object of a triple. The triples+  -- returned are those in the given graph for which the first selector+  -- returns true when called on the subject, the second selector returns+  -- true when called on the predicate, and the third selector returns true+  -- when called on the ojbect. A 'Nothing' parameter is equivalent to a+  -- function that always returns true for the appropriate node; but+  -- implementations may be able to much more efficiently answer a select+  -- that involves a 'Nothing' parameter rather than an @(id True)@ parameter.+  --+  -- The following call illustrates the use of select, and would result in+  -- the selection of all and only the triples that have a blank node+  -- as subject and a literal node as object:+  --+  -- > select gr (Just isBNode) Nothing (Just isLNode)+  --+  -- Note: this function may be very slow; see the documentation for the+  -- particular RDF implementation for more information.+  select    :: rdf -> NodeSelector -> NodeSelector -> NodeSelector -> Triples++  -- |Return the triples in the RDF that match the given pattern, where+  -- the pattern (3 Maybe Node parameters) is interpreted as a triple pattern.+  --+  -- The @Maybe Node@ params are interpreted as the subject, predicate, and+  -- object of a triple, respectively. @Just n@ is true iff the triple has+  -- a node equal to @n@ in the appropriate location; @Nothing@ is always+  -- true, regardless of the node in the appropriate location.+  --+  -- For example, @ query rdf (Just n1) Nothing (Just n2) @ would return all+  -- and only the triples that have @n1@ as subject and @n2@ as object,+  -- regardless of the predicate of the triple.+  query         :: rdf -> Maybe Node -> Maybe Node -> Maybe Node -> Triples++-- |An RdfParser is a parser that knows how to parse 1 format of RDF and+-- can parse an RDF document of that type from a string, a file, or a URL.+-- Required configuration options will vary from instance to instance.+class RdfParser p where++  -- |Parse RDF from the given text, yielding a failure with error message or+  -- the resultant RDF.+  parseString :: forall rdf. (RDF rdf) => p -> T.Text -> Either ParseFailure rdf++  -- |Parse RDF from the local file with the given path, yielding a failure with error+  -- message or the resultant RDF in the IO monad.+  parseFile   :: forall rdf. (RDF rdf) => p -> String     -> IO (Either ParseFailure rdf)++  -- |Parse RDF from the remote file with the given HTTP URL (https is not supported),+  -- yielding a failure with error message or the resultant graph in the IO monad.+  parseURL    :: forall rdf. (RDF rdf) => p -> String -> IO (Either ParseFailure rdf)+++-- |An RdfSerializer is a serializer of RDF to some particular output format, such as+-- NTriples or Turtle.+class RdfSerializer s where+  -- |Write the RDF to a file handle using whatever configuration is specified by+  -- the first argument.+  hWriteRdf     :: forall rdf. (RDF rdf) => s -> Handle -> rdf -> IO ()++  -- |Write the RDF to stdout; equivalent to @'hWriteRdf' stdout@.+  writeRdf      :: forall rdf. (RDF rdf) => s -> rdf -> IO ()++  -- |Write to the file handle whatever header information is required based on+  -- the output format. For example, if serializing to Turtle, this method would+  -- write the necessary \@prefix declarations and possibly a \@baseUrl declaration,+  -- whereas for NTriples, there is no header section at all, so this would be a no-op.+  hWriteH     :: forall rdf. (RDF rdf) => s -> Handle -> rdf -> IO ()++  -- |Write header information to stdout; equivalent to @'hWriteRdf' stdout@.+  writeH      :: forall rdf. (RDF rdf) => s -> rdf -> IO ()++  -- |Write some triples to a file handle using whatever configuration is specified+  -- by the first argument. +  -- +  -- WARNING: if the serialization format has header-level information +  -- that should be output (e.g., \@prefix declarations for Turtle), then you should+  -- use 'hWriteG' instead of this method unless you're sure this is safe to use, since+  -- otherwise the resultant document will be missing the header information and +  -- will not be valid.+  hWriteTs    :: s -> Handle  -> Triples -> IO ()++  -- |Write some triples to stdout; equivalent to @'hWriteTs' stdout@.+  writeTs     :: s -> Triples -> IO ()++  -- |Write a single triple to the file handle using whatever configuration is +  -- specified by the first argument. The same WARNING applies as to 'hWriteTs'.+  hWriteT     :: s -> Handle  -> Triple  -> IO ()++  -- |Write a single triple to stdout; equivalent to @'hWriteT' stdout@.+  writeT      :: s -> Triple  -> IO ()++  -- |Write a single node to the file handle using whatever configuration is +  -- specified by the first argument. The same WARNING applies as to 'hWriteTs'.+  hWriteN     :: s -> Handle  -> Node    -> IO ()++  -- |Write a single node to sdout; equivalent to @'hWriteN' stdout@.+  writeN      :: s -> Node    -> IO ()+++-- |The base URL of an RDF.+newtype BaseUrl = BaseUrl T.Text+  deriving (Eq, Ord, Show)++-- |A 'NodeSelector' is either a function that returns 'True'+--  or 'False' for a node, or Nothing, which indicates that all+-- nodes would return 'True'.+--+-- The selector is said to select, or match, the nodes for+-- which it returns 'True'.+--+-- When used in conjunction with the 'select' method of 'Graph', three+-- node selectors are used to match a triple.+type NodeSelector = Maybe (Node -> Bool)++-- |Represents a failure in parsing an N-Triples document, including+-- an error message with information about the cause for the failure.+newtype ParseFailure = ParseFailure String+  deriving (Eq, Show)++-- |A node is equal to another node if they are both the same type+-- of node and if the field values are equal.+instance Eq Node where+  (UNode bs1)    ==  (UNode bs2)     =   bs1 ==  bs2+  (BNode bs1)    ==  (BNode bs2)     =   bs1 ==  bs2+  (BNodeGen i1)  ==  (BNodeGen i2)   =  i1 == i2+  (LNode l1)     ==  (LNode l2)      =  l1 == l2+  _              ==  _               =  False++-- |Node ordering is defined first by type, with Unode < BNode < BNodeGen+-- < LNode PlainL < LNode PlainLL < LNode TypedL, and secondly by+-- the natural ordering of the node value.+--+-- E.g., a '(UNode _)' is LT any other type of node, and a+-- '(LNode (TypedL _ _))' is GT any other type of node, and the ordering+-- of '(BNodeGen 44)' and '(BNodeGen 3)' is that of the values, or+-- 'compare 44 3', GT.+instance Ord Node where+  compare = compareNode++compareNode :: Node -> Node -> Ordering+compareNode (UNode bs1)                      (UNode bs2)                      = compare bs1 bs2+compareNode (UNode _)                        _                                = LT+compareNode (BNode bs1)                      (BNode bs2)                      = compare bs1 bs2+compareNode (BNode _)                        (UNode _)                        = GT+compareNode (BNode _)                        _                                = LT+compareNode (BNodeGen i1)                    (BNodeGen i2)                    = compare i1 i2+compareNode (BNodeGen _)                     (LNode _)                        = LT+compareNode (BNodeGen _)                     _                                = GT+compareNode (LNode (PlainL bs1))             (LNode (PlainL bs2))             = compare bs1 bs2+compareNode (LNode (PlainL _))               (LNode _)                        = LT+compareNode (LNode (PlainLL bs1 bs1'))       (LNode (PlainLL bs2 bs2'))       =+  case compare bs1' bs2' of+    EQ -> compare bs1 bs2+    LT -> LT+    GT -> GT+compareNode (LNode (PlainLL _ _))            (LNode (PlainL _))               = GT+compareNode (LNode (PlainLL _ _))            (LNode _)                        = LT+compareNode (LNode (TypedL bsType1 bs1))         (LNode (TypedL bsType2 bs2))         =+  case compare bs1 bs2 of+    EQ -> compare bsType1 bsType2+    LT -> LT+    GT -> GT+compareNode (LNode (TypedL _ _))             (LNode _)                        = GT+compareNode (LNode _)                        _                                = GT++-- |Two triples are equal iff their respective subjects, predicates, and objects+-- are equal.+instance Eq Triple where+  (Triple s1 p1 o1) == (Triple s2 p2 o2) = s1 == s2 && p1 == p2 && o1 == o2++-- |The ordering of triples is based on that of the subject, predicate, and object+-- of the triple, in that order.+instance Ord Triple where+  (Triple s1 p1 o1) `compare` (Triple s2 p2 o2) =+    case compareNode s1 s2 of+      EQ -> case compareNode p1 p2 of+              EQ -> compareNode o1 o2+              LT -> LT+              GT -> GT+      GT -> GT+      LT -> LT++-- |Two 'LValue' values are equal iff they are of the same type and all fields are+-- equal.+instance Eq LValue where+  (PlainL bs1)        ==  (PlainL bs2)        =  bs1 == bs2+  (PlainLL bs1 bs1')  ==  (PlainLL bs2 bs2')  =  bs1' == bs2'    &&  bs1 == bs2+  (TypedL bsType1 bs1)    ==  (TypedL bsType2 bs2)    =  bsType1 == bsType2 &&  bs1 == bs2+  _                   ==  _                   =  False++-- |Ordering of 'LValue' values is as follows: (PlainL _) < (PlainLL _ _)+-- < (TypedL _ _), and values of the same type are ordered by field values,+-- with '(PlainLL literalValue language)' being ordered by language first and+-- literal value second, and '(TypedL literalValue datatypeUri)' being ordered+-- by datatype first and literal value second.+instance Ord LValue where+  compare = compareLValue++{-# INLINE compareLValue #-}+compareLValue :: LValue -> LValue -> Ordering+compareLValue (PlainL bs1)       (PlainL bs2)       = compare bs1 bs2+compareLValue (PlainL _)         _                  = LT+compareLValue _                  (PlainL _)         = GT+compareLValue (PlainLL bs1 bs1') (PlainLL bs2 bs2') =+  case compare bs1' bs2' of+    EQ -> compare bs1 bs2+    GT -> GT+    LT -> LT+compareLValue (PlainLL _ _)       _                 = LT+compareLValue _                   (PlainLL _ _)     = GT+compareLValue (TypedL l1 t1) (TypedL l2 t2) =+  case compare t1 t2 of+    EQ -> compare l1 l2+    GT -> GT+    LT -> LT++-- String representations of the various data types; generally NTriples-like.++instance Show Triple where+  show (Triple s p o) =+    printf "Triple(%s,%s,%s)" (show s) (show p) (show o)++instance Show Node where+  show (UNode uri)                   = "UNode(" ++ show uri ++ ")"+  show (BNode  i)                    = "BNode(" ++ show i ++ ")"+  show (BNodeGen genId)              = "BNodeGen(" ++ show genId ++ ")"+  show (LNode lvalue)                = "LNode(" ++ show lvalue ++ ")"++instance Show LValue where+  show (PlainL lit)               = "PlainL(" ++ T.unpack lit ++ ")"+  show (PlainLL lit lang)         = "PlainLL(" ++ T.unpack lit ++ ", " ++ T.unpack lang ++ ")"+  show (TypedL lit dtype)         = "TypedL(" ++ T.unpack lit ++ "," ++ show dtype ++ ")"++------------------------+-- Prefix mappings++-- |Represents a namespace as either a prefix and uri, respectively,+--  or just a uri.+data Namespace = PrefixedNS  T.Text T.Text -- prefix and ns uri+               | PlainNS     T.Text            -- ns uri alone++instance Eq Namespace where+  (PrefixedNS _ u1) == (PrefixedNS _ u2)  = u1 == u2+  (PlainNS      u1) == (PlainNS      u2)  = u1 == u2+  (PrefixedNS _ u1) == (PlainNS      u2)  = u1 == u2+  (PlainNS      u1) == (PrefixedNS _ u2)  = u1 == u2++instance Show Namespace where+  show (PlainNS           uri)  =  T.unpack uri+  show (PrefixedNS prefix uri)  =  printf "(PrefixNS %s %s)" (T.unpack prefix) (T.unpack uri)++-- |An alias for a map from prefix to namespace URI.+newtype PrefixMappings   = PrefixMappings (Map T.Text T.Text)+  deriving (Eq, Ord)+instance Show PrefixMappings where+  -- This is really inefficient, but it's not used much so not what+  -- worth optimizing yet.+  show (PrefixMappings pmap) = printf "PrefixMappings [%s]" mappingsStr+    where showPM      = show . PrefixMapping+          mappingsStr = List.intercalate ", " (map showPM (Map.toList pmap))++-- |A mapping of a prefix to the URI for that prefix.+newtype PrefixMapping = PrefixMapping (T.Text, T.Text)+  deriving (Eq, Ord)+instance Show PrefixMapping where+  show (PrefixMapping (prefix, uri)) = printf "PrefixMapping (%s, %s)" (show prefix) (show uri)+++-----------------+-- Internal canonicalize functions, don't export++-- |Canonicalize the given 'T.Text' value using the 'T.Text'+-- as the datatype URI.+{-# NOINLINE canonicalize #-}+canonicalize :: T.Text -> T.Text -> T.Text+canonicalize typeTxt litValue =+  case Map.lookup typeTxt canonicalizerTable of+    Nothing   ->  litValue+    Just fn   ->  fn litValue++-- A table of mappings from a 'T.Text' URI (reversed as+-- they are) to a function that canonicalizes a T.Text+-- assumed to be of that type.+{-# NOINLINE canonicalizerTable #-}+canonicalizerTable :: Map T.Text (T.Text -> T.Text)+canonicalizerTable =+  Map.fromList [(integerUri, _integerStr), (doubleUri, _doubleStr),+                (decimalUri, _decimalStr)]+  where+    integerUri =  "http://www.w3.org/2001/XMLSchema#integer"+    decimalUri =  "http://www.w3.org/2001/XMLSchema#decimal"+    doubleUri  =  "http://www.w3.org/2001/XMLSchema#double"++_integerStr, _decimalStr, _doubleStr :: T.Text -> T.Text+_integerStr = T.dropWhile (== '0')++-- exponent: [eE] ('-' | '+')? [0-9]++-- ('-' | '+') ? ( [0-9]+ '.' [0-9]* exponent | '.' ([0-9])+ exponent | ([0-9])+ exponent )+_doubleStr s = T.pack $ show (read $ T.unpack s :: Double)++-- ('-' | '+')? ( [0-9]+ '.' [0-9]* | '.' ([0-9])+ | ([0-9])+ )+_decimalStr s =     -- haskell double parser doesn't handle '1.'..,+  case T.last s of   -- so we add a zero if that's the case and then parse+    '.' -> f (s `T.snoc` '0')+    _   -> f s+  where f s' = T.pack $ show (read $ T.unpack s' :: Double)
src/Data/RDF/Utils.hs view
@@ -1,13 +1,11 @@  module Data.RDF.Utils (-  t2s, s2t, hPutStrRev, canonicalize+  t2s, s2t, hPutStrRev ) where  import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) import qualified Data.ByteString as B-import Data.Map(Map)-import qualified Data.Map as Map import System.IO  -- |A convenience function for converting from a bytestring to a string.@@ -25,40 +23,3 @@ hPutStrRev :: Handle -> T.Text -> IO () hPutStrRev h bs = B.hPutStr h ((encodeUtf8 . T.reverse) bs) --- |Canonicalize the given 'T.Text' value using the 'FastString'--- as the datatype URI.-{-# NOINLINE canonicalize #-}-canonicalize :: T.Text -> T.Text -> T.Text-canonicalize typeFs litValue =-  case Map.lookup typeFs canonicalizerTable of-    Nothing   ->  litValue-    Just fn   ->  fn litValue---- A table of mappings from a FastString URI (reversed as--- they are) to a function that canonicalizes a T.Text--- assumed to be of that type.-{-# NOINLINE canonicalizerTable #-}-canonicalizerTable :: Map T.Text (T.Text -> T.Text)-canonicalizerTable =-  Map.fromList [(integerUri, _integerStr), (doubleUri, _doubleStr),-                (decimalUri, _decimalStr)]-  where-    integerUri = mkFsUri "http://www.w3.org/2001/XMLSchema#integer"-    decimalUri = mkFsUri "http://www.w3.org/2001/XMLSchema#decimal"-    doubleUri  = mkFsUri "http://www.w3.org/2001/XMLSchema#double"-    mkFsUri :: String -> T.Text-    mkFsUri uri = s2t $! uri--_integerStr, _decimalStr, _doubleStr :: T.Text -> T.Text-_integerStr = T.dropWhile (== '0')---- exponent: [eE] ('-' | '+')? [0-9]+--- ('-' | '+') ? ( [0-9]+ '.' [0-9]* exponent | '.' ([0-9])+ exponent | ([0-9])+ exponent )-_doubleStr s = T.pack $ show (read $ T.unpack s :: Double)---- ('-' | '+')? ( [0-9]+ '.' [0-9]* | '.' ([0-9])+ | ([0-9])+ )-_decimalStr s =     -- haskell double parser doesn't handle '1.'..,-  case T.last s of   -- so we add a zero if that's the case and then parse-    '.' -> f (s `T.snoc` '0')-    _   -> f s-  where f s' = T.pack $ show (read $ T.unpack s' :: Double)
src/Rdf4hParseMain.hs view
@@ -1,8 +1,7 @@ module Main where -import Data.RDF+import Data.RDF.Types import Data.RDF.TriplesGraph- import Text.RDF.RDF4H.NTriplesParser import Text.RDF.RDF4H.NTriplesSerializer import Text.RDF.RDF4H.TurtleParser@@ -162,7 +161,7 @@ -- the version for the library as a whole, as given in rdf4h.cabal. -- TODO: should get this from cabal file rather than duplicating i here. version :: String-version = "0.9.1"+version = "1.0.2"  options :: [OptDescr Flag] options =
src/Text/RDF/RDF4H/Interact.hs view
@@ -16,7 +16,7 @@  import qualified Data.Text as T -import Data.RDF+import Data.RDF.Types import Data.RDF.Utils() import Data.RDF.TriplesGraph() import Data.RDF.MGraph()
src/Text/RDF/RDF4H/NTriplesParser.hs view
@@ -3,11 +3,9 @@  module Text.RDF.RDF4H.NTriplesParser(   NTriplesParser(NTriplesParser), ParseFailure-)--where+) where -import Data.RDF+import Data.RDF.Types import Text.RDF.RDF4H.ParserUtils import Data.Char(isLetter, isDigit, isLower) import qualified Data.Map as Map
src/Text/RDF/RDF4H/NTriplesSerializer.hs view
@@ -5,7 +5,7 @@   NTriplesSerializer(NTriplesSerializer) ) where -import Data.RDF+import Data.RDF.Types import Data.RDF.Utils import qualified Data.Text as T import Data.Text.Encoding
src/Text/RDF/RDF4H/ParserUtils.hs view
@@ -2,7 +2,7 @@   _parseURL, justTriples ) where -import Data.RDF+import Data.RDF.Types  import Network.URI import Network.HTTP
src/Text/RDF/RDF4H/TurtleParser.hs view
@@ -7,7 +7,8 @@  where -import Data.RDF+import Data.RDF.Types+import Data.RDF.Utils import Data.RDF.Namespace import Text.RDF.RDF4H.ParserUtils import Text.Parsec
src/Text/RDF/RDF4H/TurtleSerializer.hs view
@@ -7,7 +7,8 @@  where -import Data.RDF+import Data.RDF.Types+import Data.RDF.Query import Data.RDF.Namespace import Data.RDF.Utils import qualified Data.Text as T
src/Text/RDF/RDF4H/XmlParser.hs view
@@ -5,7 +5,8 @@   parseXmlRDF, getRDF ) where -import Data.RDF+import Data.RDF.Types+import Data.RDF.Utils import qualified Data.Map as Map import Control.Arrow import Text.XML.HXT.Core