Here is example 1:

class clsP[T with Str[T] ] { 
  virtual proc prcP (x:T) { println$ x; } 
}

instance[U, V with Str[U], clsP[V]] clsP[U ** V] {
  proc prcP(x: U ** V) { 
    match x with 
    | ?u ,, ?v => println$ u; prcP$ v; //<---------
    endmatch;
  }
}

instance[U, V with Str[U], Str[V]] clsP[U * V] {
  proc prcP(x: U * V) { 
    match x with 
    | ?u , ?v => println$ u; println$ v; 
    endmatch;
  }
}

open [T] clsP[T];

prcP (1,2.2,"Hello", ("x",99),22L);

Output:

~/felix>flx --test=build/release pp
1
2.2
Hello
(x, 99)
22

Note this is a "flat" implementation.  The polymorphic
recursion happens ONLY where indicated.

Example 2:

class clsP[T with Str[T] ] { 
  virtual proc prcP (x:T) { println$ x; } 
}

instance[U, V with Str[U], clsP[V]] clsP[U ** V] {
  proc prcP(x: U ** V) { 
    match x with 
    | ?u ,, ?v => prcP$ u; prcP$ v; 
    endmatch;
  }
}

instance[U, V with Str[U], clsP[V]] clsP[U * V] {
  proc prcP(x: U * V) { 
    match x with 
    | ?u , ?v => prcP u; prcP$ v; 
    endmatch;
  }
}

open [T] clsP[T];

prcP (1,2.2,"Hello", ("x",99),22L);

~/felix>flx --test=build/release pp
1
2.2
Hello
x
99
22

This one is recursive, that is, it handles nested tuples by the same
mechanism.

In both cases the "T" instance is presented as a default.
This is much the same as no default and an instance for T.

Both these patterns of usage could be "generated by the parser" as it were
by a single operation like:

        // flat version
        for x in (1,2.2, "Hello", (*"X",99), 22L) do with Str;
                println$ x; 
        done

        // recursive version
        recfor x in ... do with Str; println$ x; done

the tricky bit here is the "with Str". What this means is:

for the code in the loop body to work, we need certain overloads
open: for println we need str, which is in Str.

In general the loop body can only use polymorphic functions on the
loop variable (and the property may be transitive to dependent
variables in a more complex example). This means either parametrically
polymorphic, or, a type class virtual, in which case we must specify
the typeclass. The tricky bit is saying what types to open it on.
Another way is to not do it at all, and make the programmer
open it explicitly (it's then part of the body). Not sure that would
work (probably would).


--
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