Utility Classes :: Typeclass

The Typeclass class is all about future-proofing. Say you have a function that, as a contrived example, adds two objects:

def add(a, b):
    return a + b

Now, if you wanted to restrict this function to only operating on numbers. One possibility would be to use the IsOneOf() utility class like so:

Number = IsOneOf(int, float, long, complex)

@accepts(Number, Number)
@returns(Number)
def add(a, b):
    return a + b

That's all fine and dandy, and it works. The downside to this approach is that you've excluded yourself from using the Decimal class from the decimal module, which offers much better precision. "No problem," you say, "I'll just add Decimal to the IsOneOf instance":

Number = IsOneOf(int, float, long,
                 complex, decimal.Decimal)

@accepts(Number, Number)
@returns(Number)
def add(a, b):
    return a + b

Ok, now say you want your function to operate on objects from the Numeric package? You see what I'm getting at.

The solution is to use typeclasses. You feed the Typeclass() constructor a list of types and/or classes, and Typeclass figures out the interface common to all these types. The Typeclass instance will then approve any object that implements this set of methods.

So, let's try that earlier example again, this time using typeclasses:

Number = Typeclass(int, float, long, complex)

@accepts(Number, Number)
@returns(Number)
def add(a, b):
    return a + b

Now, without changing the Number typeclass, you can use decimal.Decimals or objects from Numeric freely.

To get you started, we've provided a whole set of typeclasses built around the built-in types. Get to know them; they're your friend.

Details

Valid XHTML 1.0 Transitional