I have a value which is a query, Query (Rel r). I would like to
recover the columns and types used in the query. The ShowLabel
instance looks like the way to go, but I was not sure how to recover
the ReCons/RecNil value structure necessary. My first attempt is
below. "def" is defined as "Query (Rel r)":
unRel :: (Rel r) -> r
unRel r = undefined
tableColumns :: ModelTable -> [String]
tableColumns (ModelTable _ _ _ def _) = recordLabels . unRel . snd .
runQueryRel $ def
The types work out but the undefined in unRel causes a runtime error.
Looking at the instances for ShowLabels, I found the culprit:
instance (FieldTag f,ShowLabels r) => ShowLabels (RecCons f a r) where
recordLabels x@(RecCons _ r) = consFieldName x : recordLabels r
Even though consFieldName never looks at its argument, the pattern
match causes the failure. I modified the ShowLabels instance so it
makes a lazy pattern match:
instance (FieldTag f,ShowLabels r) => ShowLabels (RecCons f a r) where
recordLabels ~x@(RecCons _ r) = consFieldName x : recordLabels r
And lo and behold, it works! Now - is that advisable? Can anyone see a
problem with other portions of the system? There are several other
instances in HDBRec.hs where it looks like lazy matches should be
made. What's nice is, if the RecCons values really are needed, they
are still available to those that supplied them.
I'll submit a patch if it seems like a reasonable change.
Justin
|