There are several features of typeclass that are mandatory
to make them actually useful.

The program below demonstrates the first feature: inheritance.

////////////////////////////////////////
#import <flx.flxh>

typeclass Eq[t] {
  virtual fun xeq: t * t -> bool;
  virtual fun xne: t * t -> bool;
}

typeclass Cmp[t with Eq[t]] {
  virtual fun xlt: t * t -> bool;
  virtual fun xgt: t * t -> bool;
  virtual fun xle: t * t -> bool;
  virtual fun xge: t * t -> bool;
}

instance Eq[int] {
  fun xeq: int * int -> bool = "$1==$2";  
  fun xne: int * int -> bool = "$1!=$2";  
}

instance Cmp[int] {
  fun xlt: int * int -> bool = "$1<$2" ;
  fun xgt: int * int -> bool = "$1>$2" ;
  fun xle: int * int -> bool = "$1<=$2" ;
  fun xge: int * int -> bool = "$1>=$2" ;
}

fun feq[with Eq[int]] (x:int,y:int) => xeq(x,y);
fun geq[with Cmp[int]] (x:int,y:int) => xeq(x,y);

print$ feq(1,2); endl;
////////////////////////////////////

In Haskell I think you'd write:

class Eq t => Cmp t ...

The intent is the same: to be comparable with <,>,<=,>=
you must also have equality.

Note the inheritance 'propagates' to instances: instance
Cmp[int] is incomplete unless instance Eq[int] is also 
defined.

Another useful example of this is the usual relationship
between:

        input_iterator
        output_iterator
        forward_iterator
        bidirectional_iterator
        random_iterator

Note Haskell cannot support this:

        typeclass input_iterator[it,vl] {
                virtual fun deref: it -> vl;
                virtual proc post_incr: &it;
        }
        
        typeclass output_iterator[it,vl] {
                virtual proc store: it * vl;
                virtual proc post_incr: &it;
        }

because it requires TWO type parameters, Haskell only
allows one [Felix is better at typeclasses than Haskell .. :]

Note I wrote 'store', since the C++ construction is unsound.
[C++ requires you to write *out++ = vl; for output iterators]

This creates an ambiguity. It must be resolved like:

        typeclass iterator[it,vl] {
                virtual proc post_incr: &it;
        }

        typeclass input_iterator[it,vl with iterator[it,vl] 
        {
                virtual fun deref ..
        }

        typeclass output_iterator[it,vl with iterator[it,vl] 
        {
                virtual proc store ..
        }


                          iterator
                             /\
to form a lattice     input  .. output
                             \/
                             forward
                              |
                              bidirectional
                              |
                              random


In particular, all 'bases' must be like C++ virtual bases:
shared as shown.

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to