prowdsponsor / esqueleto

Bare bones, type-safe EDSL for SQL queries on persistent backends.
http://hackage.haskell.org/package/esqueleto
BSD 3-Clause "New" or "Revised" License
178 stars 51 forks source link

Add function valJ (was keyE). #69

Closed erikd closed 10 years ago

erikd commented 10 years ago

Given a value, keyE lifts the Key for that value into the query expression.

keyE :: Esqueleto query expr backend =>
        Value (Key entity) -> expr (Value (Key entity))

This function (not totally happy with the name) solves a particular problem I met in my code base. I have a function unValueKey like this:

unValueKey :: Value (Key entity) -> Int64
unValueKey k =
    case (unKey . unValue) k of
        PersistInt64 x -> x
        _ -> error "unValueKey : Bad PersistValue."

and some times in a where_ clause I would do:

  t ^. TableChairId ==.  valkey (unValueKey kid)

The problem is the composition of valkey with unValueKey. Given this function composition, GHC infers a type of:

Esqueleto query expr backend => Value (Key entity1) -> expr (Value (Key entity))

which does not constrain the entity type parameter of the output to be the same as the input. Without that constraint, the above is non-sensical.

To fix this, the type signature of keyE requires that input and output entity type paramer are identical.

I would have added a test, but I really don't think this can go wrong :-).

meteficha commented 10 years ago

Off the top of my head, isn't keyE = val . unValue a valid definition for this problem?

erikd commented 10 years ago

Wow, yes, your version works correctly too (both giving the correct results and give a type error where it should).

However, the resulting function is much more general and the keyE name no longer makes sense.

Any suggestions for a name? Or a description of what it does? I'm pretty sure I don't actually understand what its doing.

meteficha commented 10 years ago

It's almost val, but for something that is a Value already. Perhaps valJ with J for join? Naming's too damn hard :).

erikd commented 10 years ago

Still doesn't explain what its actually doing. If I had an understanding of that, I might be better able to name it.

erikd commented 10 years ago

I've updated the PR renaming it to valJ and improving the documentation.

erikd commented 10 years ago

Felipe, I can rebase those two commits into a single one if you'd like.

meteficha commented 10 years ago

Thanks, no worries about rebasing! Released as esqueleto-1.4.2.