I think this approach is not possible without involving some fairly ugly unsafeInterleaveIO/unsafePerformIO calls. A simple example using a common web programming example: support I have a multi-user blog site, where each user can have multiple entries. I would model this using standard Haskell datatypes as: data Entry = Entry { title :: String, content :: String } data Blogger = Blogger { name :: String, entries :: [Entry] } Obviously we'll need some kind of blogger loading function: getBloggerByName :: String -> IO Blogger Either this will load up all entries (a potentially incredibly costly operation) or use unsafe IO down the road. Especially when using database connections, this can be incredibly bad: the connection could be closed, the SQL statement could be reused by another request, etc. My persistent library follows a similar approach to what Chris describes, though with a very different syntax. You can see a very similar example on the documentation site[1]. Michael [1] http://docs.yesodweb.com/book/persistent/#relations On Wed, Sep 29, 2010 at 12:01 PM, Ozgur Akgun <ozgurakgun@gmail.com> wrote:
OK, I am rephrasing it a bit then :) I definitely don't think this would be trivial to implement. However, I'd expect a decent solution to this problem, not to have special combinators to describe relations between data types, but let the user model their data using plain haskell data types, and infer the associated table structure just by looking at the data types. I'll give this a harder thought once I find the time. There is the huge barrier of TH, stopping me from playing with things like this. Anyway, have fun! :)
On 29 September 2010 10:41, Chris Eidhof <chris@eidhof.nl> wrote:
On 28 sep 2010, at 17:33, Ozgur Akgun wrote:
How do you define relationships between data types?
Well, why is it any different from other fields? From one of your examples [1], I'd expect you to have a list of questions in the Quiz data type, and if necessary, a quiz field in the Question data type. This might be a bit tricky but certainly achievable [2].
This is really tricky. For example, consider storing a large tree in the database:
data Tree = Node Int Tree Tree | Leaf Int
This means you need to read the entire tree from the database. Or consider cyclic datastructures (such as the example you gave). How do you store this? The only way to inspect this is using a library like data-reify [1].
I think the problem might be a bit harder than you suspect.
Another way to solve it is using Sebastiaan Visser's framework, described in his paper [2], but that's also rather complicated.
-chris
[1]: http://hackage.haskell.org/package/data-reify [2]: http://github.com/downloads/sebastiaanvisser/msc-thesis/wgp10-genstorage.pdf
-- Ozgur Akgun
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe