instance (FromField a) => FromRow (Map (Either Int Text) a)
One of our APIs queries one of a number of tables, and return all of the columns (I know, wonderful design)
In a runtime language one might marshal the row to a dictionary and then write it out as JSON.
postgresql-simple does not seem to have easy support for capturing a row as a Map, so I'm experimentally working on writing instance (FromField a) => FromRow (Map (Either Int Text) a), where the Either is the name or the column number depending on if the name is available for that column. I don't think my hacky version is production-ready yet but such an instance might be useful to have in the library itself. Or perhaps I'm missing a more obvious way to do this?
Sorry for not responding earlier.
I've taken this approach on a few of my projects. e.g.
data AttrName a = AttrName !ByteString a
instance FromField a => FromField (AttrName a) where
fromField f mv = AttrName (fromJust (name f)) <$> fromField f mv
Uhh, I'm not sure when name returns Nothing. I don't think it does, because the postgres convention is that unnamed columns are provided the name column1, column2, etc, but don't quote me on that. The underlying libpq fname C call would return Nothing when called on null pointer, but that shouldn't ever happen in haskell-land with vanilla postgresql-simple. So the fact that name returns Maybe ByteString instead of ByteString might just be a minor thing I overlooked in the API.
In any case, it would probably be more efficient to handle column1 etc as an integer; whether or not that makes a tangible difference in your use case, I don't know. It would definitely be more efficient to split the columns into two maps, though, one for ints, the other for descriptive names
As for the possibility of including AttrName in postgresql-simple, or take it one step further with instance (FromField a) => FromRow (Map Text a), I don't know, I haven't thought about it much. Maybe? I suppose it all depends on how often people are writing this sort of thing, and to what extent we can accommodate most similar use cases with one approach.