mam pewne predykaty, np:kombinacja Pointfree funkcja w Pythonie
is_divisible_by_13 = lambda i: i % 13 == 0
is_palindrome = lambda x: str(x) == str(x)[::-1]
i chcą logicznie połączyć je jako w:
filter(lambda x: is_divisible_by_13(x) and is_palindrome(x), range(1000,10000))
Pytanie brzmi teraz: Czy taka kombinacja jest napisane w pointfree style, takie jak:
filter(is_divisible_by_13 and is_palindrome, range(1000,10000))
To oczywiście nie jest pożądany efekt, ponieważ wartość prawdy funkcji lambda to True
i and
i or
są operatorami zwierającymi. Najbliższą rzeczą, jaką wymyśliłem, było zdefiniowanie klasy P
, która jest prostym kontenerem predykatów, który implementuje __call__()
i ma metody łączenia predykatów. Definicja P
następująco:
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
z P
mogę się tworzyć nowe orzeczenie, które jest połączeniem predykatach tak:
P(is_divisible_by_13).and_(is_palindrome)
, która jest równoważna do powyższej funkcji lambda. Jest to bliższe temu, co chciałbym mieć, ale nie jest ono również bezprzedmiotowe (punkty są teraz samymi orzeczeniami zamiast ich argumentami). Teraz drugie pytanie brzmi: czy istnieje lepsza lub krótsza droga (może bez nawiasów i kropek) do łączenia predykatów w Pythonie niż używanie klas takich jak P
i bez używania funkcji (lambda)?
Wydaje się starasz strasznie ciężko, aby niefunkcjonalny język zachowywać się jak język funkcjonalnej. Czy jesteś przywiązany do Pythona? –
@Eric: Tak, rodzaj. Mój kod Pythona jest osadzony w projekcie C++ i nie mogę po prostu przejść do innego języka. –