
On Wed, Nov 19, 2008 at 11:50 AM, Warren Harris
Now perhaps the in-memory list part was a bad conclusion since the queries can be decorated with translation functions capable of streaming the results out to another channel. However, the use of a universal type for the values would still seem to be required since there is no way to implement type-indexed values when the queries themselves are expressed as an abstract datatype rather than as functions. Am I overlooking something?
If the type of the input determines the type of the output, and the type of the input can be determined statically, then I think you are overlooking this technique. But if your application requires that each input expression be sent to the remote client before type information can be determined, then you are right. In the case of HaskellDB, each operator/term in the Query monad enriches the type information available. Of course, that enrichment happens at compile time and occurs via type inference. For example, assuming two tables T1 and T2, with columns T1col and T2col, this expression: simpleQuery = do t1 <- table T1 t2 <- table T2 restrict ( .. some expression ...) project (t1 ! T1col1 # t2 ! T2col1) Gives a type similar to Query (RecCons T1Col1 Int (RecCons T2 Col2 Int RecNil)). RecCons and RecNil are types that allow a list to be built at the type level. The list carries the column names and types in the resulting projection. The type information is used to ensure queries only refer to columns that exist, datatypes are compared sensibly, etc. If in your case you can build that kind of structure based purely on the "input language" operators/terms, then it seems you could build the entire "output expression" in one shot. But again, if input and output have to be interleaved then I think you are stuck. Justin