Marcin 'Qrczak' Kowalczyk:
> Also I was not able to unify callN series from
> <http://qrczak.ids.net.pl/qforeign.tar.gz> (QForeign.hs).

I only had a quick look at QForeign.hs, so I'm not sure whether
this will help (do you really need that odd chaining of conversion
functions? and why do you pass what seem to be conversion 
functions as parameters, do they not follow from the types?), 
but anyway..

If the problem is how to have a single overloaded wrapper function
for parameter and result conversion in foreign calls of variable types, 
then I played with similar problems when I was thinking about a 
high-level layer on top of the now deprecated Haskell/JNI.
 
I attach an example of what such a wrapper could look like, but
even if you could adapt it to your problem, my experience was that
it is somewhat at the border of Haskell's type system. So you are
often forced to use odd workarounds, and if you have to combine
two pieces of code that use mutually incompatible workarounds, 
the game is over. In other words, the code might work as it stands,
but it might be quite fragile with respect to changes and extensions.

For instance, if the base case for callN wasn't IO a, the two instance 
declarations would overlap; if you don't use functions as type dummies, 
you need explicit type declarations all over the place and tend to get 
"unresolved overloadings" instead of real type errors where you want 
them, etc.

> Is it possible to have some clever classes with instances for tuples
> that would make some kinds of operations definable for all tuples
> at once?

The problem with tuples is that each length of tuple comes as a separate
piece of *syntax* in Haskell, not built in a compositional way from tuples 
of smaller length. Type classes enable meta-programming based on types,
but not based on syntax..

If you are happy with the isomorphism 

    (T1 x T2 x ...) <-> (T1 x (T2 x (...)))

you could get a slightly better handle on the problem. Currently, this 
would make the syntax a bit awkward because of the nesting, so here 
is a question to Haskell users and implementers: should/could Haskell offer
associative type- and data-constructors? In particular, do we really need 
tuple-construction to be non-associative? That is, do we need the 
distinction between the two types in the isomorphism?

If (a,b,c) would simply stand for (a , (b , c)), it should be possible to
define some more operations on n-tuples using type classes. We lose 
some structure, but (a) what good is this structure if we have to 
repeat our function definitions for each length of tuple, and (b) the 
structure is easily recovered:

data T a = T a   -- T for tuple

T (a,b,c) would still differ from T (a, T (b,c)), but (a,b,c) would be
the same as (a,(b,c)).
[(,) would just be a right-associative infix constructor]

There might be some technical issues in implementing this, but note 
that the rows in TREX extensible records use associative and 
commutative construction and matching (using extra constraints to 
guarantee uniqueness of commutative matching), so it is not impossible.

Claus

tut.hs

Reply via email to