How to create functors?
Steven D'Aprano
steven at REMOVE.THIS.cybersource.com.au
Thu Aug 20 11:25:48 CEST 2009
On Thu, 20 Aug 2009 01:36:14 -0700, Paul Rubin wrote:
> Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes:
>> As near as I can tell, a functor is just an object which is callable
>> like a function without actually being implemented as a function, e.g.:
>
> No it's not anything like that either, at least as I'm used to the term
> in programming or in mathematics. Maybe it's used other ways though.
According to Wikipedia, functor can be used as a synonym for "function
object":
http://en.wikipedia.org/wiki/Function_object
which is what I was thinking of. So it seems there are at least two
meanings for the word, neither of which seems to apply to this thread :)
> As I'm used to it, it's a feature of certain static type systems. The
> notion isn't that useful in Python
I find the Haskell page entirely opaque and unintelligible. Well, perhaps
not *entirely* opaque, but pretty close: it assumes a mathematical
sophistication that I don't think I even had when I was getting my maths
degree, let alone can remember two decades later. (Pity the poor VB
coders wondering what Haskell is good for...) The Wikipedia page is a
little better, but it's section on Examples is laughable -- the examples
are as unintelligible to this reader as the description before them.
But let me try an example to see if I've got it right:
class Int2StrFunctor:
def map1(self, n):
if type(n) is not int:
raise TypeError('argument must be an int')
return "-"*n
def map2(self, f):
if type(f) is not type(lambda: None):
raise TypeError('argument must be a function')
# assume f takes an int, and returns another int
def inner(n):
return self.map1(f(n))
return inner
The functor can take an int and return a string:
>>> F = Int2StrFunctor() # F is a functor
>>> F.map1(3)
'---'
It can also take a function (of int -> int) and return a new function
(int -> str):
>>> def myfunc(n):
... return n+2
...
>>> f = F.map2(myfunc)
>>> f(3)
'-----'
>>> f(4)
'------'
There's nothing special about the methods map1() and map2(), I could call
them anything I like, or even do this:
>>> def __call__(self, arg):
... if type(arg) is int:
... return self.map1(arg)
... else:
... return self.map2(arg)
...
>>> Int2StrFunctor.__call__ = __call__
>>>
>>> F(2)
'--'
>>> F(myfunc)(0)
'--'
There are some technical restrictions on functors, relating to the sorts
of functions and types (strictly "categories") they can accept,
presumably to make them mathematically well-behaved.
Have I got it correct?
--
Steven
More information about the Python-list
mailing list