From: Justin B. <jgb...@gm...> - 2008-01-24 18:48:47
|
All, After building a query, it usually has a type such as: Query (Rel (RecCons SomeField (Expr SomeType) (RecCons AnotherField (Expr AnotherType) (... RecNil) ... ) I would like to recover the type of each column, much like you can recover the name of each field. I didn't see an existing way to do this, but there is a FieldType value and a FieldDesc alias defined in FieldType.hs which looked promising. FieldType represents the Haskell type associated with a field (Int, Bool, etc.), while FieldDesc is just a tuple holding a FieldType and a Bool indicating if the field is nullable. I came up with this typeclass to recover column type information: -- | Class which retrieves a field description from a given type. class ExprType e where fieldType :: e -> FieldDesc -- | Class which returns a list of field descriptions. Used with -- Record types. class ExprTypes r where fieldTypes :: r -> [FieldDesc] Some of the more interesting instances of ExprType: -- If an expression represents a type which can be recovered, we can recover -- the type of the entire expression instance (ExprType a) => ExprType (Expr a) where ... -- A Maybe type is nullable, so set the second item in the tuple to True. instance (ExprType a) => ExprType (Maybe a) where fieldType ~(Just e) = ((fst . fieldType $ e), True) -- We can recover the length of a bounded string and create an appropriate BStrT value instance (Size n) => ExprType (BoundedString n) where fieldType b = (BStrT (listBound b), False) I defined ExprTypes instances on Records much like the ShowLabels instances are defined in HDBRec.hs: instance ExprTypes RecNil where fieldTypes _ = [] instance (ExprType e, ExprTypes r) => ExprTypes (RecCons f e r) where fieldTypes ~f@(RecCons e r) = let getFieldType :: RecCons f a r -> a getFieldType = undefined in (fieldType . getFieldType $ f) : fieldTypes r instance ExprTypes r => ExprTypes (Record r) where fieldTypes r = fieldTypes (r RecNil) Does this seem patch worthy? To recover type information from any Query type would require that the ExprTypes context be added to existing functions. I think it would have to be added everywhere the ShowLabels context is found. Would it make sense to add this context to the other types of DB operations (update/delete/insert)? Justin |
From: Bjorn B. <bri...@cs...> - 2008-01-24 20:29:28
|
On Jan 24, 2008, at 19:48 , Justin Bailey wrote: > All, > > After building a query, it usually has a type such as: > > Query (Rel (RecCons SomeField (Expr SomeType) (RecCons AnotherField > (Expr AnotherType) (... RecNil) ... ) > > I would like to recover the type of each column, much like you can > recover the name of each field. I didn't see an existing way to do > this, but there is a FieldType value and a FieldDesc alias defined in > FieldType.hs which looked promising. FieldType represents the Haskell > type associated with a field (Int, Bool, etc.), while FieldDesc is > just a tuple holding a FieldType and a Bool indicating if the field is > nullable. > > I came up with this typeclass to recover column type information: > > -- | Class which retrieves a field description from a given type. > class ExprType e where > fieldType :: e -> FieldDesc > > -- | Class which returns a list of field descriptions. Used with > -- Record types. > class ExprTypes r where > fieldTypes :: r -> [FieldDesc] > > Some of the more interesting instances of ExprType: > > -- If an expression represents a type which can be recovered, we > can recover > -- the type of the entire expression > instance (ExprType a) => ExprType (Expr a) where > ... > > -- A Maybe type is nullable, so set the second item in the tuple > to True. > instance (ExprType a) => ExprType (Maybe a) where > fieldType ~(Just e) = ((fst . fieldType $ e), True) > > -- We can recover the length of a bounded string and create an > appropriate BStrT value > instance (Size n) => ExprType (BoundedString n) where > fieldType b = (BStrT (listBound b), False) > > I defined ExprTypes instances on Records much like the ShowLabels > instances are defined in HDBRec.hs: > > instance ExprTypes RecNil where > fieldTypes _ = [] > > instance (ExprType e, ExprTypes r) => ExprTypes (RecCons f e r) > where > fieldTypes ~f@(RecCons e r) = > let getFieldType :: RecCons f a r -> a > getFieldType = undefined > in (fieldType . getFieldType $ f) : fieldTypes r > > instance ExprTypes r => ExprTypes (Record r) where > fieldTypes r = fieldTypes (r RecNil) > > Does this seem patch worthy? To recover type information from any > Query type would require that the ExprTypes context be added to > existing functions. I think it would have to be added everywhere the > ShowLabels context is found. Would it make sense to add this context > to the other types of DB operations (update/delete/insert)? This looks good to me. I don't quite see why it would be necessary to add ExprTypes constraints to the existing functions, since they don't use the fieldTypes function. What is it that you want to be able to do? /Bjorn |
From: Justin B. <jgb...@gm...> - 2008-01-24 22:10:42
|
On Jan 24, 2008 12:29 PM, Bjorn Bringert <bri...@cs...> wrote: > This looks good to me. Excellent, I'll polish it and submit. If you have any naming suggestions, don't hesitate to send them. > > I don't quite see why it would be necessary to add ExprTypes > constraints to the existing functions, since they don't use the > fieldTypes function. What is it that you want to be able to do? I'm still getting used to typeclasses and I see what you are saying. I thought that, in order to use fieldTypes on a given Query, I'd need to ensure all types used by that query had the ExprTypes constraint. Just a misunderstanding on my part. Justin |