Tôi có một số vị từ, ví dụ:Pointfree chức năng kết hợp trong Python
is_divisible_by_13 = lambda i: i % 13 == 0
is_palindrome = lambda x: str(x) == str(x)[::-1]
và muốn một cách logic kết hợp chúng như trong:
filter(lambda x: is_divisible_by_13(x) and is_palindrome(x), range(1000,10000))
Câu hỏi đặt ra hiện nay: Có thể kết hợp như vậy được viết bằng một pointfree phong cách, chẳng hạn như:
filter(is_divisible_by_13 and is_palindrome, range(1000,10000))
Điều này tất nhiên không có hiệu quả mong muốn vì giá trị chân lý của hàm lambda là True
và and
và or
là các toán tử ngắn mạch. Điều gần nhất tôi đưa ra là định nghĩa một lớp P
là một thùng chứa vị ngữ đơn giản triển khai __call__()
và có các phương thức and_()
và or_()
để kết hợp các biến vị ngữ. Định nghĩa của P
là như sau:
import copy
class P(object):
def __init__(self, predicate):
self.pred = predicate
def __call__(self, obj):
return self.pred(obj)
def __copy_pred(self):
return copy.copy(self.pred)
def and_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) and predicate(x)
return self
def or_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) or predicate(x)
return self
Với P
bây giờ tôi có thể tạo ra một vị mới mà là sự kết hợp của các vị từ như thế này:
P(is_divisible_by_13).and_(is_palindrome)
tương đương với chức năng lambda trên. Điều này đến gần hơn với những gì tôi muốn có, nhưng nó cũng không phải là pointfree (các điểm bây giờ là các biến vị ngữ thay vì các đối số của chúng). Bây giờ câu hỏi thứ hai là: Có cách nào tốt hơn hoặc ngắn hơn (có thể không có dấu ngoặc đơn và dấu chấm) để kết hợp các biến vị ngữ trong Python hơn là sử dụng các lớp như P
và không sử dụng hàm lambda?
Có vẻ như bạn đang cố gắng hết sức để làm cho một ngôn ngữ không hoạt động giống như một ngôn ngữ chức năng. Bạn có liên kết với Python không? –
@Eric: Có, loại. Mã Python của tôi được nhúng trong một dự án C++ và tôi không thể chuyển sang ngôn ngữ khác. –