On Aug 20, 2009, at 5:25 AM, Steven D'Aprano wrote:

On Thu, 20 Aug 2009 01:36:14 -0700, Paul Rubin wrote:

Steven D'Aprano <ste...@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.


To this reader -- an Rb coder -- the examples were pretty clear.


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?


I don't think so. Paul Rubin's square example was, I thought, particularly instructive.

Charles Yeomans
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to