pythonic-fp-fptools 5.3.0__tar.gz → 5.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/.github/workflows/static.yml +2 -2
  2. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/CHANGELOG.rst +11 -2
  3. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/PKG-INFO +2 -2
  4. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/Makefile +2 -2
  5. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/gen_conf.py +1 -0
  6. pythonic_fp_fptools-5.4.0/docs/source/_static/custom.css +3 -0
  7. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/releases.rst +3 -1
  8. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/pyproject.toml +1 -1
  9. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/__init__.py +1 -4
  10. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/either.py +96 -52
  11. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/function.py +6 -6
  12. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/lazy.py +29 -28
  13. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/maybe.py +31 -21
  14. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/state.py +42 -33
  15. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/.gitignore +0 -0
  16. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/LICENSE +0 -0
  17. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/README.rst +0 -0
  18. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/requirements.txt +0 -0
  19. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/_static/.gitkeep +0 -0
  20. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/_templates/.gitkeep +0 -0
  21. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/function.rst +0 -0
  22. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/index.rst +0 -0
  23. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/lazy.rst +0 -0
  24. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/monads/either.rst +0 -0
  25. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/monads/index.rst +0 -0
  26. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/monads/maybe.rst +0 -0
  27. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/api/monads/state.rst +0 -0
  28. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/changelog.rst +0 -0
  29. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/description.rst +0 -0
  30. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/index.rst +0 -0
  31. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/docs/source/usage.rst +0 -0
  32. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/__init__.pyi +0 -0
  33. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/either.pyi +0 -0
  34. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/function.pyi +0 -0
  35. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/lazy.pyi +0 -0
  36. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/maybe.pyi +0 -0
  37. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/py.typed +0 -0
  38. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/src/pythonic_fp/fptools/state.pyi +0 -0
  39. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/either/test_either.py +0 -0
  40. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/either/test_sequence_either.py +0 -0
  41. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/either/test_str_repr_either.py +0 -0
  42. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/function/test_function.py +0 -0
  43. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/lazy/test_lazy.py +0 -0
  44. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/maybe/maybe.py +0 -0
  45. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/maybe/test_sequence_maybe.py +0 -0
  46. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/maybe/test_str_repr_maybe.py +0 -0
  47. {pythonic_fp_fptools-5.3.0 → pythonic_fp_fptools-5.4.0}/tests/state/test_state.py +0 -0
@@ -6,8 +6,8 @@ on:
6
6
  workflow_dispatch:
7
7
 
8
8
  env:
9
- RELEASE: '5.2.0'
10
- DEVEL: '6.0.0'
9
+ RELEASE: '5.4.0'
10
+ DEVEL: '5.4.1'
11
11
  PYTHON: '3.14'
12
12
 
13
13
  permissions:
@@ -17,11 +17,20 @@ See `Semantic Versioning 2.0.0 <https://semver.org>`_.
17
17
  Releases and Important Milestones
18
18
  ---------------------------------
19
19
 
20
+ PyPI 5.4.0 - 2026-05-16
21
+ ~~~~~~~~~~~~~~~~~~~~~~~
22
+
23
+ EitherFlag changes.
24
+
25
+ - bugfix: fixed ``__repr__`` method to properly work with ``eval()``
26
+ - API addition: added a ``__str__`` method
27
+
28
+ Documentation now in maintenance mode.
29
+
20
30
  PyPI 5.3.0 - 2026-05-09
21
31
  ~~~~~~~~~~~~~~~~~~~~~~~
22
32
 
23
- First PyPI release in over a year with actual substative code
24
- changes.
33
+ First PyPI release in over a year with substantive code changes.
25
34
 
26
35
  - Finally happy with the Sphinx/Furo based documentation.
27
36
  - Fixed errors with MayBe and Either hashing.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-fptools
3
- Version: 5.3.0
4
- Summary: Functional Programming Tools
3
+ Version: 5.4.0
4
+ Summary: .. admonition:: Functional programming tools for Python
5
5
  Keywords: either,fp,functional,functional programming,lazy,maybe,monad,non-strict
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.13
@@ -5,8 +5,8 @@
5
5
  # - later needs to agree with pyproject.toml
6
6
  PROJECT_NAME = FP Tools Array
7
7
  PYPI_NAME = fptools
8
- RELEASE_VERSION = 5.3.0
9
- DEVEL_VERSION = 5.3.0
8
+ RELEASE_VERSION = 5.4.0
9
+ DEVEL_VERSION = 5.4.1
10
10
  CUSTOM_VERSION = 0.0.0
11
11
 
12
12
  SPHINXOPTS ?=
@@ -101,6 +101,7 @@ html_theme_options = {{
101
101
  }}
102
102
  html_theme = 'furo'
103
103
  html_static_path = ['_static']
104
+ html_css_files = ['custom.css']
104
105
 
105
106
  rst_epilog = """
106
107
  .. |RELEASE_STRING| replace:: {release_string}
@@ -0,0 +1,3 @@
1
+ dl.field-list > dt {
2
+ text-transform: none !important;
3
+ }
@@ -8,7 +8,9 @@ PyPI releases
8
8
  +=====================================================================================+==============+
9
9
  | `development <https://grscheller.github.io/pythonic-fp-fptools/development/html/>`_ | |
10
10
  +-------------------------------------------------------------------------------------+--------------+
11
- | `v5.3.0 <https://grscheller.github.io/pythonic-fp-fptools/release/html/>`_ | 2026-05-09 |
11
+ | `v5.4.0 <https://grscheller.github.io/pythonic-fp-fptools/release/html/>`_ | 2026-05-16 |
12
+ +-------------------------------------------------------------------------------------+--------------+
13
+ | v5.3.0 | 2026-05-09 |
12
14
  +-------------------------------------------------------------------------------------+--------------+
13
15
  | v5.2.0 | 2026-01-13 |
14
16
  +-------------------------------------------------------------------------------------+--------------+
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "pythonic-fp-fptools"
7
- version = "5.3.0"
7
+ version = "5.4.0"
8
8
  readme = "README.rst"
9
9
  requires-python = ">=3.13"
10
10
  authors = [
@@ -13,10 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- Functional Programming Tools
17
- ============================
18
-
19
- .. admonition:: Functional programming tools for Python.
16
+ .. admonition:: Functional programming tools for Python
20
17
 
21
18
  Functions as first class objects, Lazy (non-strict) function evaluation,
22
19
  and classical Functional Programming data structures.
@@ -20,8 +20,9 @@
20
20
 
21
21
  - Module implements a left biased either monad
22
22
 
23
- - left value is intended for the "expected" result
24
- - right value gives information on something "exceptional"
23
+ - Left values is intended for "expected" results.
24
+ - Right value gives information on the "unexpected"
25
+ perhaps "exceptional" result.
25
26
 
26
27
  - left and right values can be the same or different types
27
28
  - in a boolean context
@@ -39,7 +40,8 @@
39
40
 
40
41
  .. tip::
41
42
 
42
- Right ``Either`` instances can be used as sentinel values.
43
+ Right Either instances, as well as LEFT and RIGHT EitherFlag,
44
+ can be used as hidden sentinel values.
43
45
 
44
46
  """
45
47
 
@@ -54,19 +56,44 @@ from .maybe import MayBe
54
56
  @final
55
57
  class EitherFlag(SBool):
56
58
  """
57
- .. admonition:: Type for ``LEFT`` and ``RIGHT`` singleton flags
59
+ .. admonition:: LEFT and RIGHT singleton flags
58
60
 
59
- Boolean-like type for signaling the ``Either`` initializer
60
- to make a left or right ``Either`` instance.
61
+ Boolean-like type which can
62
+
63
+ - signal the Either initializer to create either
64
+ a left or right Either instance
65
+ - be combined like Booleans with Python bitwise operators
61
66
 
62
67
  """
63
68
 
64
69
  def __repr__(self) -> str:
65
70
  """
66
- .. admonition:: string representation
71
+ .. admonition:: repr string
72
+
73
+ Construct one of two strings:
74
+
75
+ - 'EitherFlag{True)' for the LEFT EitherFlag
76
+ - 'EitherFlag{False)' for the RIGHT EitherFlag
77
+
78
+ :returns: A string to construct the appropriate
79
+ EitherFlag singleton.
80
+
81
+ """
82
+ if self:
83
+ return 'EitherFlag(True)'
84
+ return 'EitherFlag(False)'
85
+
86
+
87
+ def __str__(self) -> str:
88
+ """
89
+ .. admonition:: user string
67
90
 
68
- Two values 'LEFT' or 'RIGHT' for the truthy and falsy
69
- singletons respectfully. Also the default user strings.
91
+ Construct one of two strings:
92
+
93
+ - 'LEFT' for a ``LEFT`` EitherFlag
94
+ - 'RIGHT' for a ``RIGHT`` EitherFlag
95
+
96
+ :returns: A string meaningful to an end user.
70
97
 
71
98
  """
72
99
  if self:
@@ -76,17 +103,17 @@ class EitherFlag(SBool):
76
103
 
77
104
  LEFT: Final[EitherFlag] = EitherFlag(True)
78
105
  """
79
- .. admonition:: truthy Either flag
106
+ .. admonition:: The truthy EitherFlag
80
107
 
81
- Used by ``Either`` initializer to make a right ``Either``.
108
+ Used by the Either initializer to make a left Either.
82
109
 
83
110
  """
84
111
 
85
112
  RIGHT: Final[EitherFlag] = EitherFlag(False)
86
113
  """
87
- .. admonition:: falsy Either flag
114
+ .. admonition:: The falsy EitherFlag
88
115
 
89
- Used by ``Either`` initializer to make a right ``Either``.
116
+ Used by the Either initializer to make a right Either.
90
117
 
91
118
  """
92
119
 
@@ -94,17 +121,14 @@ RIGHT: Final[EitherFlag] = EitherFlag(False)
94
121
  @final
95
122
  class Either[L, R]:
96
123
  """
97
- .. admonition:: Either monad
124
+ .. admonition:: either monad
98
125
 
99
126
  Left biased Either monad.
100
127
 
101
128
  - immutable semantics
102
129
  - contains either a "left" or a "right" item, but not both
103
130
  - hashable
104
-
105
- .. important::
106
-
107
- An ``Either`` is immutable once initialized.
131
+ - immutable
108
132
 
109
133
  """
110
134
 
@@ -120,13 +144,14 @@ class Either[L, R]:
120
144
 
121
145
  def __init__(self, value: L | R, side: EitherFlag = LEFT) -> None:
122
146
  """
123
- .. admonition:: initializer
147
+ .. admonition:: init
124
148
 
125
- Initialize ``Either`` instance as a "left" or a "right".
149
+ Initialize Either instance as a left or a right Either.
126
150
 
127
151
  :param value: The value contained in the ``Either``.
128
152
  :param side: Determines whether to produce
129
- a left or right ``Either``.
153
+ a "left" or a "right" ``Either``.
154
+ :type side: EitherFlag
130
155
 
131
156
  """
132
157
  self._value: L | R
@@ -141,14 +166,15 @@ class Either[L, R]:
141
166
 
142
167
  def __hash__(self) -> int:
143
168
  """
144
- .. admonition:: hashability
169
+ .. admonition:: hash
145
170
 
146
171
  If contained value hashable, use its hash value in
147
- the hash calculation, otherwise use item's identity.
172
+ the hash calculation, otherwise use the value's identity.
148
173
 
149
- - should be safe, the ``Either`` holds a reference to the value
150
- - lazily calculates hash value, then caches it
151
- - hash also depends if ``Either`` is a left or right
174
+ - Should be safe, the ``Either`` holds
175
+ a reference to the value.
176
+ - Lazily calculates hash value, then caches it.
177
+ - The hash also depends if the Either is a left or right.
152
178
 
153
179
  """
154
180
  if self._hash is None:
@@ -162,8 +188,11 @@ class Either[L, R]:
162
188
  """
163
189
  .. admonition:: bool
164
190
 
165
- - left ``Either`` is truthy
166
- - right ``Either`` is falsy
191
+ - left Eithers are truthy
192
+ - right Eithers are falsy
193
+
194
+ :returns: ``True`` if ``Either`` is a left,
195
+ ``False`` if a right.
167
196
 
168
197
  """
169
198
  return self._side is LEFT
@@ -172,7 +201,9 @@ class Either[L, R]:
172
201
  """
173
202
  .. admonition:: len
174
203
 
175
- Either always contains just one value.
204
+ An Either always contains just one value.
205
+
206
+ :returns: 1
176
207
 
177
208
  """
178
209
  return 1
@@ -181,9 +212,13 @@ class Either[L, R]:
181
212
  """
182
213
  .. admonition:: equality comparison
183
214
 
184
- Compare ``Either`` to another object. Compare first
215
+ Compare Either to another object. Compare first
185
216
  by identity, then value.
186
217
 
218
+ :param other: The object to be compared.
219
+ :returns: True only if other is a Either of the same side
220
+ containing objects which compare as equal.
221
+
187
222
  """
188
223
  if not isinstance(other, type(self)):
189
224
  return False
@@ -200,9 +235,11 @@ class Either[L, R]:
200
235
 
201
236
  def __iter__(self) -> Iterator[L]:
202
237
  """
203
- .. admonition:: iterate
238
+ .. admonition:: iter
239
+
240
+ Yield the contained value if Either is a left.
204
241
 
205
- Iterate ``value`` if a left ``Either``.
242
+ :yields: The contained value if a left.
206
243
 
207
244
  """
208
245
  if self:
@@ -219,6 +256,8 @@ class Either[L, R]:
219
256
 
220
257
  Where ``repr_value = repr(value)``.
221
258
 
259
+ :returns: A string to reproduce the ``Either``.
260
+
222
261
  """
223
262
  if self:
224
263
  return 'Either(' + repr(self._value) + ', LEFT)'
@@ -235,6 +274,8 @@ class Either[L, R]:
235
274
 
236
275
  Where ``str_value = str(value)``.
237
276
 
277
+ :returns: A string meaningful to an end user.
278
+
238
279
  """
239
280
  if self:
240
281
  return '< ' + str(self._value) + ' | >'
@@ -251,12 +292,12 @@ class Either[L, R]:
251
292
 
252
293
  .. warning::
253
294
 
254
- Unsafe method ``get``. Will raise ``ValueError`` if ``Either``
295
+ Unsafe method get. Will raise ValueError if the Either
255
296
  is a right.
256
297
 
257
298
  .. tip::
258
299
 
259
- Best practice is to first check the ``Either`` in
300
+ Best practice is to first check the Either in
260
301
  a boolean context.
261
302
 
262
303
  """
@@ -271,7 +312,8 @@ class Either[L, R]:
271
312
 
272
313
  Get the value if a left.
273
314
 
274
- :returns: ``MayBe[L]``
315
+ :returns: MayBe wrapping a left value.
316
+ :rtype: MayBe[L]
275
317
 
276
318
  """
277
319
  if self._side == LEFT:
@@ -284,7 +326,8 @@ class Either[L, R]:
284
326
 
285
327
  Get the value if a right.
286
328
 
287
- :returns: ``MayBe[R]``
329
+ :returns: MayBe wrapping a right value.
330
+ :rtype: MayBe[R]
288
331
 
289
332
  """
290
333
  if self._side == RIGHT:
@@ -295,10 +338,11 @@ class Either[L, R]:
295
338
  """
296
339
  .. admonition:: map right
297
340
 
298
- Map function ``f`` over the contents of a right ``Either``.
341
+ Map the function f over the contents of a right Either.
299
342
 
300
- :param f: function to map a right value
301
- :returns: A new ``Either`` if a right, otherwise ``self``.
343
+ :param f: A function to map a right value.
344
+ :returns: A new Either instance if a right,
345
+ otherwise itself.
302
346
 
303
347
  """
304
348
  if self._side == LEFT:
@@ -309,10 +353,11 @@ class Either[L, R]:
309
353
  """
310
354
  .. admonition:: map
311
355
 
312
- Map function ``f`` over left ``Either``.
356
+ Map the function f over a left Either.
313
357
 
314
- :param f: Function used to map left values.
315
- :returns: A new ``Either`` if a left, otherwise ``self``.
358
+ :param f: A function used to map a left value.
359
+ :returns: A new Either if a left,
360
+ otherwise itself.
316
361
 
317
362
  """
318
363
  if self._side == RIGHT:
@@ -323,7 +368,8 @@ class Either[L, R]:
323
368
  """
324
369
  .. admonition:: map except
325
370
 
326
- Map ``f`` over left ``Either`` with a right fallback upon exception.
371
+ Map function f over left Either with a right fallback
372
+ upon exception.
327
373
 
328
374
  :param f: Function used to map left values.
329
375
  :param fallback_right: Fallback value if exception thrown.
@@ -362,8 +408,7 @@ class Either[L, R]:
362
408
  """
363
409
  .. admonition:: bind
364
410
 
365
- Flatmap function ``f`` over a left value. Propagate right
366
- values.
411
+ Flatmap function f over a left value. Propagate right values.
367
412
 
368
413
  :param f: Function to bind.
369
414
  :returns: A new Either if a left, otherwise itself.
@@ -379,13 +424,13 @@ class Either[L, R]:
379
424
  """
380
425
  .. admonition:: bind except
381
426
 
382
- Flatmap function ``f`` over ``Either``, with fallback upon
427
+ Flatmap function f over the Either, with fallback upon
383
428
  exception. Propagate right values.
384
429
 
385
430
  :param f: Function to bind over values.
386
431
  :param fallback_right: Fallback value if exception thrown.
387
432
  :returns: A successfully bound left, a propagated right,
388
- or a right with a fallback value.
433
+ or a right with a fallback value.
389
434
 
390
435
  .. warning::
391
436
 
@@ -423,12 +468,11 @@ class Either[L, R]:
423
468
  """
424
469
  .. admonition:: sequence
425
470
 
426
- ``Sequence[Either[U, V]]`` -> ``Either[Sequence[U], V]``
471
+ Sequence[Either[U, V]] -> Either[Sequence[U], V]
427
472
 
428
- If all ``Either`` are lefts, then return an ``Either``
429
- of the ``Sequence`` of contained left values. Otherwise
430
- return a right ``Either`` containing the first right
431
- encountered.
473
+ If all Either are lefts, then return an Either of the
474
+ Sequence of contained left values. Otherwise return
475
+ a right Either containing the first right encountered.
432
476
 
433
477
  """
434
478
  sequenced_list: list[U] = []
@@ -40,7 +40,7 @@ def swap[U, V, R](f: Callable[[U, V], R]) -> Callable[[V, U], R]:
40
40
  Swap arguments of a two argument function.
41
41
 
42
42
  :param f: Two argument function.
43
- :returns: A version of ``f`` with its arguments swapped.
43
+ :returns: A version of f with its arguments swapped.
44
44
 
45
45
  """
46
46
  return lambda v, u: f(u, v)
@@ -52,8 +52,8 @@ def compose[D, T, R](f: Callable[[D], T], g: Callable[[T], R]) -> Callable[[D],
52
52
 
53
53
  Function Composition
54
54
 
55
- :param f: Function called first with domain ``D`` and range ``T``.
56
- :param g: Function called on result with domain ``T`` and range ``R``.
55
+ :param f: Function called first with domain D and range T.
56
+ :param g: Function called on result with domain T and range R.
57
57
  :returns: The composite function ``g∘f(d) = g(f(d))``
58
58
 
59
59
  """
@@ -66,7 +66,7 @@ def negate[**P](f: Callable[P, bool]) -> Callable[P, bool]:
66
66
 
67
67
  Take a predicate and return its negation.
68
68
 
69
- :param f: a function ``f`` which returns a bool
69
+ :param f: A function ``f`` which returns a bool
70
70
  :returns: the function ``not f``
71
71
 
72
72
  """
@@ -85,7 +85,7 @@ def sequenced[R](f: Callable[..., R]) -> Callable[[tuple[Any]], R]:
85
85
 
86
86
  :param f: Function with just positional parameters
87
87
  :returns: An equivalent function taking a tuple of
88
- the arguments to ``f``.
88
+ the arguments to f.
89
89
 
90
90
  """
91
91
  def ff(tupled_args: tuple[Any]) -> R:
@@ -102,7 +102,7 @@ def partial[**P, R](f: Callable[P, R], *args: Any) -> Callable[..., R]:
102
102
  arguments left to right.
103
103
 
104
104
  :param f: Function with just positional arguments.
105
- :param args: Arguments to partially apply to ``f``.
105
+ :param args: Arguments to partially apply to f.
106
106
 
107
107
  .. warning::
108
108
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  - *class* **Lazy** - Delay evaluation of single argument functions
21
21
  - *function* **lazy** - Delay evaluation of functions taking any number of arguments
22
- - *function* **real_lazy** - Caching version of ``lazy``.
22
+ - *function* **real_lazy** - Caching version of lazy.
23
23
 
24
24
  """
25
25
 
@@ -40,8 +40,8 @@ class Lazy[D, R]:
40
40
 
41
41
  .. tip::
42
42
 
43
- Make a function "non-strict" by passing some of
44
- its arguments wrapped in Lazy instances.
43
+ Make functions "non-strict" by passing some of
44
+ their arguments wrapped in Lazy instances.
45
45
 
46
46
  """
47
47
 
@@ -54,9 +54,9 @@ class Lazy[D, R]:
54
54
  Delayed evaluation of a single argument function.
55
55
 
56
56
  :param f: Single argument function.
57
- :param d: Argument to be passed to ``f``.
58
- :param pure: If true, cache the result for future ``eval`` method calls.
59
- :returns: A Lazy instance which can evaluate ``f(d)`` at a later time.
57
+ :param d: Argument to be passed to f.
58
+ :param pure: If true, cache the result for future eval method calls.
59
+ :returns: A Lazy instance which can evaluate f(d) at a later time.
60
60
 
61
61
  """
62
62
  self._f: Final[Callable[[D], R]] = f
@@ -72,8 +72,8 @@ class Lazy[D, R]:
72
72
 
73
73
  A Lazy becomes truthy when evaluated.
74
74
 
75
- :returns: ``True`` when evaluated.
76
- :returns: ``False`` when not evaluated.
75
+ :returns: True when evaluated.
76
+ :returns: False when not evaluated.
77
77
 
78
78
  """
79
79
  return self._evaluated
@@ -84,8 +84,8 @@ class Lazy[D, R]:
84
84
 
85
85
  Evaluate function with its argument.
86
86
 
87
- - cache result or exception if ``pure is True``
88
- - reevaluate if ``pure is False``
87
+ - Cache result or exception if pure is True.
88
+ - Reevaluate if pure is False.
89
89
 
90
90
  """
91
91
  if not (self._pure and self._evaluated):
@@ -110,9 +110,9 @@ class Lazy[D, R]:
110
110
 
111
111
  Check if a valid result was obtained.
112
112
 
113
- :returns: ``MayBe()`` if not yet evaluated.
114
- :returns: ``MayBe(True)`` if a result was gotten.
115
- :returns: ``MayBe(False)`` if an exception was thrown.
113
+ :returns: MayBe() if not yet evaluated.
114
+ :returns: MayBe(True) if a result was gotten.
115
+ :returns: MayBe(False)` if an exception was thrown.
116
116
 
117
117
  """
118
118
  return self._exceptional.bind(lambda x: MayBe(not x))
@@ -123,9 +123,9 @@ class Lazy[D, R]:
123
123
 
124
124
  Check if exception thrown.
125
125
 
126
- :returns: ``MayBe()`` if not yet evaluated.
127
- :returns: ``MayBe(True)`` if an exception was thrown.
128
- :returns: ``MayBe(False)`` if exception not thrown.
126
+ :returns: MayBe() if not yet evaluated.
127
+ :returns: MayBe(True) if an exception was thrown.
128
+ :returns: MayBe(False) if exception not thrown.
129
129
 
130
130
  """
131
131
  return self._exceptional
@@ -137,12 +137,12 @@ class Lazy[D, R]:
137
137
  Get result only if evaluated and no exceptions occurred,
138
138
  otherwise return an alternate value.
139
139
 
140
- :param alt: Optional alternate value to return if ``Lazy``
140
+ :param alt: Optional alternate value to return if Lazy
141
141
  is not evaluated or exceptional.
142
142
  :returns: The successfully evaluated result
143
- or `alt` if given.
144
- :raises ValueError: if ``Lazy`` not evaluated,
145
- or exceptional and ``alt`` not given.
143
+ or an alternate value if given.
144
+ :raises ValueError: If Lazy not evaluated or exceptional,
145
+ and an alternate value not given.
146
146
 
147
147
  """
148
148
  if self._evaluated and self._result:
@@ -185,13 +185,13 @@ def lazy[**P, R](
185
185
  """
186
186
  .. admonition:: delayed evaluations
187
187
 
188
- Function returning a delayed evaluation of a function of an arbitrary number
189
- of positional arguments.
188
+ Function returning a delayed evaluation of a function of
189
+ an arbitrary number of positional arguments.
190
190
 
191
191
  :param f: Function whose evaluation is to be delayed.
192
- :param args: Positional arguments to be passed to ``f``.
192
+ :param args: Positional arguments to be passed to f.
193
193
  :param kwargs: Any kwargs given are ignored.
194
- :returns: a ``Lazy`` object wrapping the evaluation of ``f``
194
+ :returns: A Lazy instance wrapping the evaluation of f.
195
195
 
196
196
  """
197
197
  return Lazy(sequenced(f), args, pure=False)
@@ -203,13 +203,14 @@ def real_lazy[**P, R](
203
203
  """
204
204
  .. admonition:: cached delayed evaluations
205
205
 
206
- Function returning a delayed evaluation of a function of an
207
- arbitrary number of positional arguments. Evaluation is cached.
206
+ Function returning a delayed evaluation of a function of
207
+ an arbitrary number of positional arguments. The evaluation
208
+ is cached.
208
209
 
209
210
  :param f: Function whose evaluation is to be delayed.
210
- :param args: Positional arguments to be passed to ``f``.
211
+ :param args: Positional arguments to be passed to f.
211
212
  :param kwargs: Any kwargs given are ignored.
212
- :returns: a ``Lazy`` object wrapping the evaluation of ``f``
213
+ :returns: A Lazy instance wrapping the evaluation of f.
213
214
 
214
215
  """
215
216
  return Lazy(sequenced(f), args)
@@ -44,11 +44,11 @@ class MayBe[D]:
44
44
 
45
45
  def __init__(self, item: D | _Sentinel = _sentinel) -> None:
46
46
  """
47
- .. admonition:: initialize
47
+ .. admonition:: init
48
48
 
49
- Initialize ``MayBe`` with 1 or 0 items.
49
+ Initialize MayBe with 1 or 0 items.
50
50
 
51
- :param item: Optional item for the ``MayBe``.
51
+ :param item: Optional item for the MayBe instance.
52
52
 
53
53
  .. important::
54
54
 
@@ -61,13 +61,13 @@ class MayBe[D]:
61
61
 
62
62
  def __hash__(self) -> int:
63
63
  """
64
- .. admonition:: hashability
64
+ .. admonition:: hash
65
65
 
66
66
  If contained item hashable, use its hash value in
67
67
  the hash calculation, otherwise use item's identity.
68
68
 
69
- - should be safe, the ``MayBe`` holds a reference to the item
70
- - lazily calculates hash value, then caches it
69
+ - should be safe, the MayBe holds a reference to the item.
70
+ - Lazily calculates hash value, then caches it.
71
71
 
72
72
  """
73
73
  if self._hash is None:
@@ -84,6 +84,8 @@ class MayBe[D]:
84
84
 
85
85
  Truthy when not empty.
86
86
 
87
+ :returns: True if not empty, False if empty.
88
+
87
89
  """
88
90
  return self._item is not _sentinel
89
91
 
@@ -100,9 +102,11 @@ class MayBe[D]:
100
102
  """
101
103
  .. admonition:: equality comparison
102
104
 
103
- Compare ``MayBe`` to another object. Compare first
105
+ Compare MayBe instance to another object. Compare first
104
106
  by identity, then value.
105
107
 
108
+ :returns: True only if other object is a MayBe with
109
+ a corresponding item, or both empty.
106
110
  """
107
111
  if not isinstance(other, type(self)):
108
112
  return False
@@ -116,7 +120,7 @@ class MayBe[D]:
116
120
  """
117
121
  .. admonition:: iterate
118
122
 
119
- :yields: The contained ``item`` if non-empty.
123
+ :yields: The contained item if non-empty.
120
124
 
121
125
  """
122
126
  if self:
@@ -124,13 +128,16 @@ class MayBe[D]:
124
128
 
125
129
  def __repr__(self) -> str:
126
130
  """
127
- .. admonition:: representation string
131
+ .. admonition:: repr string
128
132
 
129
133
  Return the strings
130
134
 
131
- :returns: 'MayBe()' if empty
132
- :returns: 'MayBe(repr_item)' if not empty
133
- where ``repr_item = repr(item)``.
135
+ - 'MayBe()' if empty
136
+ - 'MayBe(repr_item)' if not empty
137
+
138
+ Where ``repr_item = repr(item)``.
139
+
140
+ :returns: A string to reproduce the MayBe.
134
141
 
135
142
  """
136
143
  if self:
@@ -148,6 +155,8 @@ class MayBe[D]:
148
155
 
149
156
  Where ``str_item = str(item)``.
150
157
 
158
+ :returns: A string meaningful to an end user.
159
+
151
160
  """
152
161
  if self:
153
162
  return 'MayBe(' + str(self._item) + ')'
@@ -165,19 +174,18 @@ class MayBe[D]:
165
174
  Return the item if it exists, otherwise an optional
166
175
  alternate item.
167
176
 
168
- :param alt: Optional alternative item to return if``MayBe`` empty.
177
+ :param alt: Optional alternative item to return if MayBe empty.
169
178
  :returns: The item if it exists.
170
179
  :raises ValueError: When an alternate item is not provided but needed.
171
180
 
172
-
173
181
  .. warning::
174
182
 
175
- Unsafe method ``get`` will raise ``ValueError`` if the
176
- ``MayBe`` is empty and an ``alt`` return item not provided.
183
+ Unsafe method get will raise ValueError if the MayBe
184
+ is empty and an alternate return item not provided.
177
185
 
178
186
  .. tip::
179
187
 
180
- Best practice is to first check the ``MayBe`` in
188
+ Best practice is to first check the MayBe in
181
189
  a boolean context.
182
190
 
183
191
  """
@@ -193,10 +201,11 @@ class MayBe[D]:
193
201
  """
194
202
  .. admonition:: Map
195
203
 
196
- Map function ``f`` over the ``MayBe``.
204
+ Map function f over the MayBe.
197
205
 
198
206
  :param f: Function used for the map.
199
- :returns: A new ``MayBe`` if not empty, otherwise ``self``.
207
+ :returns: A new MayBe instance if not empty,
208
+ otherwise itself.
200
209
 
201
210
  """
202
211
  if self:
@@ -207,10 +216,11 @@ class MayBe[D]:
207
216
  """
208
217
  .. admonition:: Bind
209
218
 
210
- Flatmap function ``f`` over the contained item, if it exists.
219
+ Flatmap function f over the MayBe.
211
220
 
212
221
  :param f: Function to bind.
213
- :returns: A new ``MayBe`` if not empty, otherwise ``self``.
222
+ :returns: A new MayBe instance if not empty,
223
+ otherwise itself.
214
224
 
215
225
  """
216
226
  return f(cast(D, self._item)) if self else cast(MayBe[U], self)
@@ -30,16 +30,18 @@ class State[S, A]:
30
30
  .. note::
31
31
 
32
32
  A monad is a value in a context. The State monad wraps neither
33
- a state nor a (value, state) pair. It wraps a transformation
34
- ``old_state -> (value, new_state)`` called a "state action".
33
+ a state nor a ``(value, state)`` pair.
34
+
35
+ It wraps a transformation ``old_state -> (value, new_state)``
36
+ called a "state action".
35
37
 
36
38
  .. admonition:: Class State
37
39
 
38
40
  Instance members:
39
41
 
40
- - Property ``run`` is the **state action**
41
- - Method ``bind`` performs state action composition
42
- - Method ``eval`` is the **run action**
42
+ - Property *run* is the **state action**
43
+ - Method *bind* performs state action composition
44
+ - Method *eval* performs the **run action**
43
45
 
44
46
  - the **run action** evaluates the **state action** by
45
47
 
@@ -48,17 +50,17 @@ class State[S, A]:
48
50
 
49
51
  Static members:
50
52
 
51
- - Method ``unit`` creates a ``State`` whose
52
- run action returns a given constant value.
53
- - Method ``get`` creates a ``State`` whose
53
+ - Method unit creates a State instance whose
54
+ run action returns the supplied constant value.
55
+ - Method get creates a State instance whose
54
56
  run action returns the current state.
55
- - Method ``set`` creates a ``State`` which
56
- ignores the old state and swaps in a new one.
57
- - Method ``modify`` creates a ``State`` which
57
+ - Method set creates a State which ignores
58
+ the old state and swaps in a new one.
59
+ - Method modify creates a State instance which
58
60
  modifies the previous state via a function.
59
- - Method ``sequence`` combine a list of ``States``
60
- into a ``State`` whose run action returns the
61
- list of generated values.
61
+ - Method sequence combine a list of State instances
62
+ into a State whose run action returns the list
63
+ of generated values.
62
64
 
63
65
  """
64
66
 
@@ -66,9 +68,11 @@ class State[S, A]:
66
68
 
67
69
  def __init__(self, run: Callable[[S], tuple[A, S]]) -> None:
68
70
  """
69
- .. admonition:: initialize
71
+ .. admonition:: init
70
72
 
71
73
  :param run: State action.
74
+ :type run: ``S -> (A, S)`` where A is the type of the
75
+ generated value and S is the type of a state.
72
76
 
73
77
  """
74
78
  self.run = run
@@ -108,13 +112,13 @@ class State[S, A]:
108
112
  """
109
113
  .. admonition:: map
110
114
 
111
- Map function ``f`` over the resulting value of a
115
+ Map function f over the resulting value of a
112
116
  state action propagating the current state.
113
117
 
114
118
  :param f: Function to map.
115
- :returns: A `State` whose run action produces ``f(a)``
116
- where ``a`` is the value produced by
117
- the run action of ``self``.
119
+ :returns: A new State instance whose run action produces f(a)
120
+ where a is the value produced by the current State
121
+ instance and just propagates the current state.
118
122
 
119
123
  """
120
124
  return self.bind(lambda a: State.unit(f(a)))
@@ -123,15 +127,14 @@ class State[S, A]:
123
127
  """
124
128
  .. admonition:: map2
125
129
 
126
- Combine two state monads, ``self`` and ``sb``, with
127
- a function. Resulting run action just propagates
128
- the current state.
130
+ Combine two state monads, self and sb, with a function.
131
+ Resulting run action just propagates the current state.
129
132
 
130
- :param sb: ``State`` to combine with ``self``.
133
+ :param sb: State instance to combine with the current instance.
131
134
  :param f: Function used by the resulting run action
132
135
  on the values produced by the run actions
133
- of ``self`` and ``sb`` from the same initial
134
- state.
136
+ of the current State instance and ``sb`` using
137
+ the same initial state.
135
138
 
136
139
  """
137
140
  return self.bind(lambda a: sb.map(lambda b: f(a, b)))
@@ -140,11 +143,10 @@ class State[S, A]:
140
143
  """
141
144
  .. admonition:: both
142
145
 
143
- Return a ``State`` whose run action returns a tuple
144
- from from the run actions from .
146
+ Return a State instance whose run action returns a tuple
147
+ from from the run actions of the current State and sb.
145
148
 
146
- :param sb: ``State`` to combine with ``self`` for the
147
- second element of tuple produced by run action.
149
+ :param sb: A State instance to be combined with the current one.
148
150
 
149
151
  """
150
152
  return self.map2(rb, lambda a, b: (a, b))
@@ -155,10 +157,10 @@ class State[S, A]:
155
157
  .. admonition:: unit
156
158
 
157
159
  Create a State whose run action returns the given
158
- constant ``b`` and propagate the present state.
160
+ constant b and propagate the present state.
159
161
 
160
162
  :param b: Value the new State's run action will return.
161
- :returns: A new ``State[ST, B]`` from a value ``b: B``.
163
+ :returns: A new State[ST, B] from a value b: B.
162
164
 
163
165
  """
164
166
  return State(lambda s: (b, s))
@@ -197,6 +199,8 @@ class State[S, A]:
197
199
  :param s: The state to swap in for current state
198
200
  :returns: State monad wrapping a state action which ignores
199
201
  any initial state passed in when evaluated.
202
+ :rtype: State[ST, tuple[()]]
203
+
200
204
  """
201
205
  return State(lambda _: ((), s))
202
206
 
@@ -206,16 +210,18 @@ class State[S, A]:
206
210
  .. admonition:: modify
207
211
 
208
212
  Modify previous state with a function. Like put, but modify
209
- previous state via ``f``.
213
+ previous state via f.
210
214
 
211
215
  :param f: Function to modify the current state.
212
216
  :returns: A State monad with a modified state.
217
+ :rtype: State[ST, tuple[()]]
213
218
 
214
219
  .. note::
215
220
 
216
221
  Will need type annotation. Static type checkers like
217
222
  mypy have no *a priori* knowledge of what ``ST``
218
223
  could be.
224
+
219
225
  """
220
226
  return State.get().bind(lambda a: State.put(f(a))) # type: ignore
221
227
 
@@ -229,7 +235,10 @@ class State[S, A]:
229
235
  run action from the original list.
230
236
 
231
237
  :param sas: A list of state monads all of type ``State[ST, AA]``.
232
- :returns: A state monad of type ``State[ST, list[AA]]``.
238
+ :returns: A state monad whose run action produces a list of
239
+ the values produced by the list of State actions
240
+ provided to the method.
241
+ :rtype: State[ST, list[AA]]
233
242
 
234
243
  .. note::
235
244