Real-World Currying Examples
Configurable Data Mapper
def create_mapper(transform_func):
def mapper(data):
return [transform_func(item) for item in data]
return mapper
## Example usage
numbers = [1, 2, 3, 4, 5]
square_mapper = create_mapper(lambda x: x ** 2)
double_mapper = create_mapper(lambda x: x * 2)
print(square_mapper(numbers)) ## [1, 4, 9, 16, 25]
print(double_mapper(numbers)) ## [2, 4, 6, 8, 10]
Authentication and Access Control
Role-Based Permission Decorator
def permission_check(required_role):
def decorator(func):
def wrapper(user, *args, **kwargs):
if user.role == required_role:
return func(user, *args, **kwargs)
raise PermissionError("Insufficient permissions")
return wrapper
return decorator
class User:
def __init__(self, name, role):
self.name = name
self.role = role
@permission_check('admin')
def delete_user(user, user_id):
print(f"User {user_id} deleted")
admin = User('Alice', 'admin')
regular_user = User('Bob', 'user')
delete_user(admin, 123) ## Success
## delete_user(regular_user, 123) ## Raises PermissionError
Configuration Management
Flexible Configuration Loader
def config_loader(default_config):
def load_config(custom_config=None):
config = default_config.copy()
if custom_config:
config.update(custom_config)
return config
return load_config
default_database_config = {
'host': 'localhost',
'port': 5432,
'database': 'myapp'
}
database_config = config_loader(default_database_config)
## Using default configuration
print(database_config())
## Overriding specific settings
custom_config = database_config({'host': '192.168.1.100'})
print(custom_config)
Network Request Handling
Parameterized Request Handler
def create_request_handler(base_url):
def handler(endpoint, method='GET'):
def execute_request(params=None):
full_url = f"{base_url}/{endpoint}"
## Simulated request logic
print(f"Executing {method} request to {full_url}")
return params
return execute_request
return handler
github_api = create_request_handler('https://api.github.com')
users_endpoint = github_api('users')
repos_endpoint = github_api('repositories')
users_endpoint()
repos_endpoint(params={'org': 'python'})
Logging and Monitoring
Configurable Logger
def create_logger(log_level):
def log(message):
print(f"[{log_level.upper()}] {message}")
return log
debug_log = create_logger('debug')
error_log = create_logger('error')
debug_log("Application started")
error_log("Critical error occurred")
Currying Techniques Comparison
| Scenario |
Benefit |
Complexity |
Use Case |
| Data Processing |
High Flexibility |
Low |
Transformations |
| Authentication |
Granular Control |
Medium |
Access Management |
| Configuration |
Modular Setup |
Low |
Dynamic Settings |
| Network Requests |
Parameterization |
Medium |
API Interactions |
| Logging |
Configurable Output |
Low |
Monitoring |
LabEx Functional Programming Insights
LabEx recommends leveraging currying for creating more adaptable and modular code structures, enabling developers to write more expressive and maintainable software solutions.
Best Practices
- Use currying for creating specialized, reusable functions
- Maintain clear and predictable function interfaces
- Balance complexity with readability
- Consider performance implications