Increse safety of parameter subsitution?
So, I've been notificing a pattern in some of my own code (and similarly in postgresql-simple code). There seems to be quite a bit of duplication of functions depending on whether or not query substitution is to be performed. For example, in postgresql-simple we have:
query :: (ToRow q, FromRow r) => Connection -> Query -> q -> IO [r]
query_ :: FromRow r => Connection -> Query -> IO [r]
queryWith :: ToRow q => RowParser r -> Connection -> Query -> q -> IO [r]
queryWith_ :: RowParser r -> Connection -> Query -> IO [r]
I was just wondering: Do you know if there's any "deep" reason for this? It seems like it would be a straight up win to have separate data constructors, e.g.
data Query =
ParameterizedQuery ByteString (exists p . ToRow p => [p])
| RawQuery ByteString
(I'm not sure the type signature actually works, but the point is that a parameter list only requires a ToRow class. It could perhaps also be split out to decouple if from ToRow, but that's a side issue.)
This is obviously not a huge deal, but it would be nice to avoid the combinatorial "explosion".
Any ideas?
Yes, you have identified one of my dissatisfactions with the current API, but I haven't thought that much about it.