Functors and their use in Python


Functional programming uses the idea of functors to help programmers create more modular, reusable, and reasonable code. They are a means to enclose a value or a function in an object and then manipulate that object without altering the original object. Functors are a potent tool for writing modular, reusable code in Python and may be implemented using classes.

Syntax

As Python functors are implemented using classes, a key component of the language, there is no special installation needed. Just build a class with an init method that accepts the original value or function as a parameter and a call method that takes the transformation function as a parameter to create a functor class in Python. The original value or function is then subjected to the transformation function, and the outcome is returned.

Algorithm

  • Define a class that takes the original value or function as a parameter in the init method.

  • Define a call method that takes the transformation function as a parameter.

  • Apply the transformation function to the original value or function.

  • Return the result of the transformation.

Example

class NumberFunctor:
   def __init__(self, value):
      self.value = value
        
   def __call__(self, f):
      return f(self.value)
    
def square(x):
   return x * x

functor = NumberFunctor(5)
result = functor(square)
print(result)

Output

25

Define a class called NumberFunctor that takes a value as a parameter in the __init__ method. We then define a __call__ method that takes a function as a parameter. In this case, the function is square. We apply square to the value in the __call__ method, and return the result. Finally, we create an instance of NumberFunctor with a value of 5, and call the functor with square as the transformation function. The result is 25, which is the square of 5.

Example

class StringFunctor:
   def __init__(self, value):
      self.value = value
        
   def __call__(self, f):
      return f(self.value)
    
def uppercase(s):
   return s.upper()

functor = StringFunctor("hello")
result = functor(uppercase)
print(result)

Output

HELLO

Create a class “StringFunctor” that takes a string as a parameter in the __init__ method and a call method that accepts a function as an argument must first be defined. The function being supplied in this instance is uppercase. Inside the call method, the string is subjected to the uppercase function, and the resultant string is returned after which the string "hello" may be used to generate an instance of StringFunctor. The transformation function used to invoke the functor is uppercase. The outcome will be the uppercase form of the original string "hello," which will be "HELLO."

Example

class Functor:
   def __init__(self, value):
      self.value = value
        
   def __call__(self, f):
      return Functor(f(self.value))
    
   def __repr__(self):
      return f"Functor({self.value})"
    
def add(x):
   def inner(y):
      return x + y
   return inner

functor = Functor(5)
result = functor(add(3))(add(3))

print(result)

Output

Functor(11)

The "Functor" class's "__call__" method takes a function as an argument and accepts a value as an input. The "add" method adds its argument to the starting value and returns a closure which allows the instantiation of a transformation function that takes the input as a functor and returns a fresh functor that increases the value of the input value. The final step is to build a 5-valued instance of "Functor" and use "add" to perform two transformations on it, increasing the value by three (3) and increasing the outcome of the first transformation by three (3). A new functor with a value of 11 is the end result.

Applications

  • Functors are versatile tools used in programming paradigms and applications.

  • In object-oriented programming, they can encapsulate behavior for reuse and define standard interfaces.

  • implement design patterns like the Strategy and Visitor patterns in OOP.

  • In functional programming, used for mapping, filtering, folds, and function composition.

  • In data pipelines, they define a standard interface for data transformations and compose transformation operations into pipelines.

  • Apply transformations to extract, filter, transform or aggregate data in data pipelines.

  • Build complex machine learning models by defining a pipeline of preprocessing, feature engineering, and model training steps.

Conclusion

A solid instrument for composing measured, reusable, and composable code is a functor empowering developers to make more information driven, object-situated, and utilitarian programming. They are ideal while building changes that can be fastened together in a composable design, and are in many cases carried out in Python utilizing classes. Programmers can write code that is more expressive, scalable, and easy to maintain with functors.

Updated on: 22-Aug-2023

347 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements