[Fencommits] fenfire-hs: FromRDF and ToRDF typeclasses

Benja Fallenstein benja.fallenstein at gmail.com
Fri Mar 16 22:03:49 EET 2007


Fri Mar 16 22:03:29 EET 2007  Benja Fallenstein <benja.fallenstein at gmail.com>
  * FromRDF and ToRDF typeclasses
diff -rN -u old-fenfire-hs/Fenfire/RDF.hs new-fenfire-hs/Fenfire/RDF.hs
--- old-fenfire-hs/Fenfire/RDF.hs	2007-03-16 22:03:49.000000000 +0200
+++ new-fenfire-hs/Fenfire/RDF.hs	2007-03-16 22:03:49.000000000 +0200
@@ -23,7 +23,10 @@
 import Fenfire.Utils
 import qualified Fenfire.Raptor as Raptor
 
-import Control.Monad.Writer (MonadWriter, tell, forM_)
+import Control.Monad.Writer (Writer, WriterT, MonadWriter, tell, forM_,
+                             runWriter)
+import Control.Monad.Reader (Reader, ask, runReader)
+import Control.Monad.State (State, get, put, modify)
 
 import Data.List (intersperse)
 import Data.Map (Map)
@@ -228,40 +231,50 @@
 
 
 --------------------------------------------------------------------------
--- Common structures
+-- FromRDF and ToRDF
 --------------------------------------------------------------------------
 
-createBNode :: String -> Graph -> Node
--- Finds a bnode id that currently has no connections in the graph.
-createBNode gid g = head $ filter test $ nodes where
-    nodes = for [1..] $ \(i :: Integer) -> BNode gid $ show i
-    test n = testMap (getConns g n Neg) && testMap (getConns g n Pos)
-    testMap m = all (Set.null . snd) (Map.toAscList m)
-
-readRDFList :: Node -> Graph -> [Node]
-readRDFList l g | l == rdf_nil = []
-                | otherwise    = (fromJust $ getOne g l rdf_first Pos)
-                   : readRDFList (fromJust $ getOne g l rdf_next Pos) g
-                   
-createRDFList :: [Node] -> String -> Graph -> (Node, Graph)
-createRDFList []     _   g = (rdf_nil, g)
-createRDFList (x:xs) gid g =
-    let (l', g') = createRDFList xs gid g
-        l = createBNode gid g'
-     in (l, foldr insert g' [(l, rdf_first, x), (l, rdf_next, l')])
-
-deleteRDFList :: Node -> Endo Graph
-deleteRDFList l g | l == rdf_nil = g
-                  | otherwise    =
-    deleteRDFList l' $ delete (l, rdf_type, rdf_List) $
-        deleteAll l rdf_first $ deleteAll l rdf_next g where
-        l' = fromJust $ getOne g l rdf_next Pos
-        
-updateRDFList :: Node -> Node -> [Node] -> String -> Endo Graph
-updateRDFList s p l gid g = update (s,p,o) g' where
-    olds = Set.toAscList $ getAll g s p Pos
-    (o,g') = createRDFList l gid $ foldr deleteRDFList g olds
-    
+type FromRdfM = Writer (Set Triple)
+
+class FromRDF a where
+    fromRDF :: Graph -> Node -> a
+    fromRDF g n = fst $ runWriter (readRDF g n)
+    
+    -- Return a value read from a graph and the triples
+    -- that were used in getting that value. When updating
+    -- a value in a graph, these triples will be replaced
+    -- by the triples generated by toRDF.
+    readRDF :: Graph -> Node -> FromRdfM a
+    
+type ToRdfM = WriterT (Set Triple) (State (String, Int))
+    
+newBNode :: ToRdfM Node
+newBNode = do (gid, i) <- get; put (gid, i+1); return $ BNode gid (show i)
+
+tellTs :: (MonadWriter (Set Triple) m) => [Triple] -> m ()
+tellTs = tell . Set.fromList
+
+class ToRDF a where
+    toRDF :: a -> ToRdfM Node
+    
+instance FromRDF a => FromRDF [a] where
+    readRDF g l | l == rdf_nil = return []
+                | otherwise    = do
+        let first = fromJust $ getOne g l rdf_first Pos
+            rest  = fromJust $ getOne g l rdf_next Pos
+        tellTs [ (l, rdf_first, first), (l, rdf_next, rest) ]
+        x  <- readRDF g first
+        xs <- readRDF g rest
+        return (x:xs)
+            
+instance ToRDF a => ToRDF [a] where
+    toRDF []     = return rdf_nil
+    toRDF (x:xs) = do l <- newBNode; first <- toRDF x; next <- toRDF xs
+                      tellTs [ (l, rdf_type, rdf_List)
+                             , (l, rdf_first, first)
+                             , (l, rdf_next, next) ]
+                      return l
+
 
 --------------------------------------------------------------------------
 -- Raptor interface




More information about the Fencommits mailing list