Skip to content

Validated

funstruct.applicative.validated

Validated: applicative error-accumulating functor.

Examples:

>>> from funstruct.applicative.validated import Validated, Valid, Invalid
>>> Validated.cond(True, 42, "err")
Valid(value=42)
>>> Validated.cond(False, 42, "err")
Invalid(errors=Cons('err', Nil()))
>>> Valid(1) * Valid(2)
Valid(value=(1, 2))
>>> Invalid("a:") * Invalid("b")
Invalid(errors='a:b')

Validated

Bases: DataType, Generic[_E, _A]

Base class for Valid/Invalid. Bifunctor over error and value types.

Source code in funstruct/applicative/validated/__init__.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class Validated(DataType, Generic[_E, _A]):
    """Base class for Valid/Invalid. Bifunctor over error and value types."""

    @property
    @abstractmethod
    def is_valid(self) -> bool: ...

    @abstractmethod
    def fold(
        self,
        on_invalid: Callable[[_E], _C],
        on_valid: Callable[[_A], _C],
    ) -> _C: ...

    def __mul__(self, other: Validated) -> Validated:
        return self.product(other)

    @classmethod
    def pure(cls, value: _A) -> Validated:
        return Valid(value)

    @staticmethod
    def valid(value: _A) -> Validated:
        return Valid(value)

    @staticmethod
    def invalid(error: _E) -> Validated:
        return Invalid(Cons.pure(error))

    @staticmethod
    def cond(test: bool, value: _A, error: _E) -> Validated:
        if test:
            return Valid(value)
        return Invalid(Cons.pure(error))

Valid dataclass

Bases: Validated, Generic[_A]

Success case.

Source code in funstruct/applicative/validated/__init__.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@dataclass(frozen=True)
class Valid(Validated, Generic[_A]):
    """Success case."""

    value: _A

    @property
    def is_valid(self) -> bool:
        return True

    def __bool__(self) -> bool:
        return True

    def fold(
        self,
        on_invalid: Callable[[_E], _C],
        on_valid: Callable[[_A], _C],
    ) -> _C:
        return on_valid(self.value)

Invalid dataclass

Bases: Validated, Generic[_E]

Failure case — accumulated errors.

Source code in funstruct/applicative/validated/__init__.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
@dataclass(frozen=True)
class Invalid(Validated, Generic[_E]):
    """Failure case — accumulated errors."""

    errors: _E

    @property
    def is_valid(self) -> bool:
        return False

    def __bool__(self) -> bool:
        return False

    def fold(
        self,
        on_invalid: Callable[[_E], _C],
        on_valid: Callable[[_A], _C],
    ) -> _C:
        return on_invalid(self.errors)