Я бы не стал менять состояние Test
, создав новый объект для возврата.Вот краткая версия, но она не обязательно хорошо масштабируется:
@classmethod
def is_not(cls, truth):
test = cls(not self.a, not self.b)
test._validity = not(truth)
return test
Это также приводит к тому, что двойной негатив становится положительным, что может быть не тем, что вы хотите.
Это напоминает образец монады.Одним из возможных способов реализации этого было бы использование монады State
из oslash
:
import oslash
class TestMonadic:
def __init__(self, a, b):
self.a = a
self.b = b
def is_not(self, truth: bool) -> oslash.State:
return lambda validity: oslash.State(lambda _: (truth != validity, self))
def validity(self, state: oslash.State):
return state.run(self)[0]
Синтаксис становится немного громоздким в python, потому что он не предназначен для этого.Возможно, имеет смысл размещать is_not
и validity
вне класса, но из-за их довольно общих имен полезно связать их с классом.(В Haskell имя функции не так важно, потому что сигнатура типа функции будет вызывать диспетчеризацию).
Вот как ваши вычисления будут выглядеть в этой структуре:
>>> t = TestMonadic(a=True, b=False)
>>> t.validity(State.get() | t.is_not(t.b))
True
>>> t.validity(State.get() | t.is_not(t.a) | t.is_not(t.b))
True
>>> t.validity(State.get() | t.is_not(t.b))
False
oslash
отсутствует evalState
, что validity()
частично делает.