I did some more work and got this to go: class Applicable[A,D,C] { virtual fun myapply : A * D -> C; }
instance[DH,DT,CH,CT] Applicable[ (DH -> CH) * (DT -> CT), DH * DT, CH * CT] { fun myapply : ((DH->CH) * (DT->CT)) * (DH * DT) -> CH * CT = | (?ah , ?at) , (?dh, ?dt) => ah dh, at dt ; } instance[AT,DH,DT,CH,CT with Applicable[AT,DT,CT] ] Applicable[ (DH->CH) ** AT, DH ** DT, CH ** CT] { fun myapply : ((DH->CH) ** AT) * (DH ** DT) -> (CH ** CT) = | (?ah ,, ?at) , (?dh ,, ?dt) => ah dh ,, myapply (at, dt) ; } var d = 1,2.0,3; var sqrint = fun (x:int) => x * x; var sqrdouble= fun (x:double) => x * x; var a = sqrint, sqrdouble , sqrint; var c = Applicable[ (int->int) * (double -> double) * (int -> int), (int * double * int), (int * double * int) ]::myapply (a, d); println$ d,c; Now the idea is to be able to write (sqrint, sqrdouble, sqrint) (1, 2.0,3) and have parallel application happen, producing (1, 4.0, 9). So "myapply" would be apply, which would be invoked by magic since that's what happens when you try to apply a non-function to data. The problem I had was even writing myapply ((sqrint, sqrdouble, sqrint), (1, 2.0,3)) didn't work: compiler said it couldn't find myapply (which was very confusing!!) Finally I discovered the reason: class Applicable[A,D,C] { virtual fun myapply : A * D -> C; } It's pretty obvious you cannot deduce the type C from the arguments of myapply in this form. If you examine the two instance you can see the problem better. For the pair, the first argument is of type: (DH->CH) * (DT->CT) and clearly we can deduce CH and CT from it. But for the tuple cons instance the type is: (DH->CH) ** AT so whilst we know CH, we don't know CT. Where we have AT we really want to say "a list of types of shape X -> Y" but this: (DH->CH) ** (DT -> CT) is a type error: the RHS of operator ** must be either a sole type variable or a tuple type (including arrays and tuple conses). And this is also suggestive but still wrong: ( (DH ** DT) -> (CH ** CT)) In fact, that's a function from a tuple to a tuple which is exactly what we want to *produce* here! I wonder how to fix this. It is clearly because the original virtual is too general. The problem in another sense is that ** doesn't commute with other combinators: you can't specify "a tuple of pairs" either, hence whilst you CAN write a function to zip two tuples into a tuple of pairs, it will have the same problem: you have to specify the return type. The funny thing is that it works for a procedure storing the result in a variable via a pointer (since the pointer type provides the result type). but you cannot encapsulate that into a function which then returns the variable (because you have to specify the variable type). -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language