Index: libcfa/src/enum.cfa
===================================================================
--- libcfa/src/enum.cfa	(revision 07e9df1e21fb57bb093460e2671a8b1e2add9d74)
+++ libcfa/src/enum.cfa	(revision fbc84cac372de119b3e9078a5ac2dbb453b501ed)
@@ -0,0 +1,16 @@
+#include "enum.hfa"
+
+#pragma GCC visibility push(default)
+
+forall(T, E| TypedEnum(T, E)) {
+    // constructors
+
+    // comparison
+    int ?==?(E l, E r) { return posE(l) == posE(r); }
+    int ?!=?(E l, E r) { return posE(l) != posE(r); }
+    int ?!=?(E l, zero_t) { return !( posE(l) == 0 ); }
+    int ?<?(E l, E r) { return posE(l) < posE(r); }
+    int ?<=?(E l, E r) { return posE(l) <= posE(r); }
+    int ?>?(E l, E r) { return posE(l) > posE(r); }
+    int ?>=?(E l, E r) {  return posE(l) >= posE(r); }
+}
Index: libcfa/src/enum.hfa
===================================================================
--- libcfa/src/enum.hfa	(revision 07e9df1e21fb57bb093460e2671a8b1e2add9d74)
+++ libcfa/src/enum.hfa	(revision fbc84cac372de119b3e9078a5ac2dbb453b501ed)
@@ -1,30 +1,36 @@
 #pragma once
 
-forall( E ) trait Bounded {
-	E lowerBound();
-	E upperBound();
-};
+forall(T) { // T is the based type of enum(T)
+    forall(E) trait Bounded {
+        E lowerBound();
+        E upperBound();
+    };
 
-forall( E | Bounded( E ) ) trait Serial {
-	unsigned fromInstance( E e );
-	E fromInt( unsigned int posn );
-	E succ( E e );
-	E pred( E e );
-};
+    forall(E| Bounded(T, E)) trait Serial {
+        unsigned fromInstance(E e);
+        E fromInt(unsigned i);
+        E succ(E e);
+        E pred(E e);
+    };
 
-forall( E, T ) trait TypedEnum {
-	T valueE( E e );
-	char * labelE( E e );
-	unsigned int posE( E e );
-};
+    // Opague Enum + TypedEnum
+    forall(E | Serial(T, E)) trait CfaEnum { 
+        char * labelE(E e);
+        unsigned int posE(E e);
+    };
 
-forall( E, T | TypedEnum( E, T ) ) {
-	// comparison
-	int ?==?( E l, E r );								// true if l and r are same enumerators	   
-	int ?!=?( E l, E r );								// true if l and r are different enumerators
-	int ?!=?( E l, zero_t );							// true if l is not the first enumerator	   
-	int ?<?( E l, E r );								// true if l is an enuemerator before r	   
-	int ?<=?( E l, E r );								// true if l before or the same as r		   
-	int ?>?( E l, E r );								// true if l is an enuemrator after r	   
-	int ?>=?( E l, E r );								// true if l after or the same as r         
+    forall(E| CfaEnum(T, E)) trait TypedEnum {
+        T valueE(E e);
+    };
+
+	forall(E | TypedEnum(T, E)) {
+		// comparison
+		int ?==?(E l, E r);								// true if l and r are same enumerators
+		int ?!=?(E l, E r);								// true if l and r are different enumerators
+		int ?!=?(E l, zero_t);							// true if l is not the first enumerator
+		int ?<?(E l, E r);								// true if l is an enuemerator before r
+		int ?<=?(E l, E r);								// true if l before or the same as r
+		int ?>?(E l, E r);								// true if l is an enuemrator after r
+		int ?>=?(E l, E r);								// true if l after or the same as r
+	}
 }
