agentm / project-m36

Project: M36 Relational Algebra Engine
The Unlicense
895 stars 48 forks source link

allow `Tupleable` instances to include default relvar name #164

Open agentm opened 6 years ago

agentm commented 6 years ago

Currently, the Tupleable interface does not include any specific binding to any relvar. @3noch suggested that the Tupleable typeclass could carry a default relvar name likely for use in define/assign/insert/update/delete operations. Tupleable values would still be able to be extracted from arbitrary queries.

3noch commented 6 years ago

You could encode this as a separate type class.

ruhatch commented 6 years ago

I guess the following would work nicely

class HasRelVarName a where
  relVarName :: RelVarName

and then we could add a default that names it using Generics?

3noch commented 6 years ago

This is exactly what I had in mind (and implemented in one of my projects). It works great.

ruhatch commented 6 years ago

Awesome ;) did you implement a default for it?

3noch commented 6 years ago

No I didn't get that far. But I'm on the fence about it anyway. I like things like that to be explicit, but certainly for toy projects it's nicer.

ruhatch commented 6 years ago

I guess it would still be reasonably explicit because you would have to write

instance HasRelVarName a where

anyway. But I guess you're right that you might as well add the string at that point. Although as mentioned in the Beam tutorial, in GHC 8.2 that can be changed to a deriving (HasRelVarName) on the type which would be nice.

ruhatch commented 6 years ago

@3noch In your definition of the class do you get an ambiguous type error? I get one on relVarName because it ignores the a.

agentm commented 6 years ago

I am thinking tentatively that there should be indeed two classes: Tupleable and something else for the relvar name. The reason is that, if Tupleable has a single hard-coded relvar name, then one would need a second Tupleable instance to marshal the Haskell values to/form a different relvar. That seems rather limiting, especially considering that Tupleable instances don't need to use all the attributes of the target relation.

Alternatively, we could stick the relvar name into the Tupleable instance while making two expression-generating APIs, one using the instance's relvar name and one using any name (like we have now). That sounds like it could clutter what should be an easy-to-use API, though.

What do you think?