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

Reply via email to