How to create functors?

Charles Yeomans charles at declareSub.com
Fri Aug 21 04:12:32 CEST 2009


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 <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.
>

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090820/85f59932/attachment.html>


More information about the Python-list mailing list