pythonic-fp-fptools 5.1.1__tar.gz → 5.2.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.
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/CHANGELOG.rst +70 -58
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/PKG-INFO +15 -12
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/README.rst +5 -4
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/pyproject.toml +10 -8
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/either.py +25 -17
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/either.pyi +1 -1
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/function.py +22 -26
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/function.pyi +2 -1
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/lazy.py +18 -22
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/maybe.py +7 -8
- pythonic_fp_fptools-5.2.0/src/pythonic_fp/fptools/py.typed +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/state.py +7 -8
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/either/test_sequence_either.py +1 -1
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/maybe/test_sequence_maybe.py +1 -1
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/.gitignore +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/LICENSE +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/__init__.py +0 -0
- /pythonic_fp_fptools-5.1.1/src/pythonic_fp/fptools/py.typed → /pythonic_fp_fptools-5.2.0/src/pythonic_fp/fptools/__init__.pyi +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/lazy.pyi +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/maybe.pyi +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/state.pyi +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/either/test_either.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/either/test_str_repr_either.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/function/test_function.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/lazy/test_lazy.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/maybe/maybe.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/maybe/test_str_repr_maybe.py +0 -0
- {pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/state/test_state.py +0 -0
|
@@ -17,22 +17,38 @@ See `Semantic Versioning 2.0.0 <https://semver.org>`_.
|
|
|
17
17
|
Releases and Important Milestones
|
|
18
18
|
---------------------------------
|
|
19
19
|
|
|
20
|
-
5.
|
|
21
|
-
|
|
20
|
+
PyPI 5.2.0 - 2026-01-13
|
|
21
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
22
|
+
|
|
23
|
+
Added function.compose back on 2025-12-04. Docstring updates for Sphinx.
|
|
24
|
+
|
|
25
|
+
PyPI 5.1.2 - 2025-09-28
|
|
26
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
27
|
+
|
|
28
|
+
Patch bump for pythonic-fp PyPI coordinated release 3.3.3.
|
|
29
|
+
|
|
30
|
+
PyPI 5.1.1 - 2025-09-09
|
|
31
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
32
|
+
|
|
33
|
+
Spotted a dependency issue when pip installing repo.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
PyPI 5.1.0 - 2025-09-09
|
|
37
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
22
38
|
|
|
23
39
|
Updated docstrings for new Sphinx docs structure. Probably just a PATCH release,
|
|
24
40
|
made it a MINOR release due to introducing .pyi files.
|
|
25
41
|
|
|
26
42
|
|
|
27
|
-
5.0.0 - 2025-08-02
|
|
28
|
-
|
|
43
|
+
PyPI 5.0.0 - 2025-08-02
|
|
44
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
29
45
|
|
|
30
46
|
Coordinated entire project pythonic-fp PyPI deployment.
|
|
31
47
|
|
|
32
48
|
- moved maybe.py and xor.py from containers, renamed xor.py -> either.py.
|
|
33
49
|
|
|
34
|
-
4.0.0 - 2025-07-13
|
|
35
|
-
|
|
50
|
+
PyPI 4.0.0 - 2025-07-13
|
|
51
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
36
52
|
|
|
37
53
|
Dropped developer status to Beta
|
|
38
54
|
|
|
@@ -42,15 +58,15 @@ Dropped developer status to Beta
|
|
|
42
58
|
TODO: After next Boring Math (bm) deployment, I should be able to archive
|
|
43
59
|
my dtools namespace repos
|
|
44
60
|
|
|
45
|
-
3.0.0 - 2025-07-06
|
|
46
|
-
|
|
61
|
+
PyPI 3.0.0 - 2025-07-06
|
|
62
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
47
63
|
|
|
48
64
|
First PyPI release as ``pythonic-fp.fptools``
|
|
49
65
|
|
|
50
66
|
- dropping dtools namespace name because there is a repo by that name.
|
|
51
67
|
|
|
52
|
-
2.0.0 - 2025-05-22
|
|
53
|
-
|
|
68
|
+
PyPI 2.0.0 - 2025-05-22
|
|
69
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
54
70
|
|
|
55
71
|
- Moved dtools.fp.err_handling to the dtools.containers PyPI project
|
|
56
72
|
|
|
@@ -60,8 +76,8 @@ First PyPI release as ``pythonic-fp.fptools``
|
|
|
60
76
|
|
|
61
77
|
- will import dtools.fp.lazy directly for this functionality
|
|
62
78
|
|
|
63
|
-
1.7.0 - 2025-04-22
|
|
64
|
-
|
|
79
|
+
PyPI 1.7.0 - 2025-04-22
|
|
80
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
65
81
|
|
|
66
82
|
Last PyPI release as dtools.fp
|
|
67
83
|
|
|
@@ -70,8 +86,8 @@ Last PyPI release as dtools.fp
|
|
|
70
86
|
- docstring changes
|
|
71
87
|
- pyproject.toml standardization
|
|
72
88
|
|
|
73
|
-
1.6.1.0 - 2025-04-17
|
|
74
|
-
|
|
89
|
+
PyPI 1.6.1.0 - 2025-04-17
|
|
90
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
75
91
|
|
|
76
92
|
- MB.sequence and XOR.sequence now return a wrapped iterator
|
|
77
93
|
|
|
@@ -85,13 +101,13 @@ Last PyPI release as dtools.fp
|
|
|
85
101
|
|
|
86
102
|
- Also noticed MB and XOR still have camelCase APIs
|
|
87
103
|
|
|
88
|
-
1.6.0 - 2025-04-07
|
|
89
|
-
|
|
104
|
+
PyPI 1.6.0 - 2025-04-07
|
|
105
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
90
106
|
|
|
91
107
|
- typing improvements
|
|
92
108
|
|
|
93
|
-
1.4.0 - 2025-03-16
|
|
94
|
-
|
|
109
|
+
PyPI 1.4.0 - 2025-03-16
|
|
110
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
95
111
|
|
|
96
112
|
- added two state changing methods to dtools.err_handling.MB
|
|
97
113
|
|
|
@@ -109,13 +125,13 @@ Last PyPI release as dtools.fp
|
|
|
109
125
|
|
|
110
126
|
- avoid using these methods in pure code
|
|
111
127
|
|
|
112
|
-
1.3.1 - 2025-02-05
|
|
113
|
-
|
|
128
|
+
PyPI 1.3.1 - 2025-02-05
|
|
129
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
114
130
|
|
|
115
131
|
- added class method sequence to class State
|
|
116
132
|
|
|
117
|
-
1.3.0 - 2025-01-17
|
|
118
|
-
|
|
133
|
+
PyPI 1.3.0 - 2025-01-17
|
|
134
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
119
135
|
|
|
120
136
|
First release as dtools.fp
|
|
121
137
|
|
|
@@ -124,25 +140,23 @@ Repo name changes.
|
|
|
124
140
|
- GitHub: fp -> dtools-fp
|
|
125
141
|
- PyPI: grscheller.fp -> dtools.fp
|
|
126
142
|
|
|
127
|
-
1.2.0 - 2025-01-04
|
|
128
|
-
|
|
143
|
+
PyPI 1.2.0 - 2025-01-04
|
|
144
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
129
145
|
|
|
130
146
|
- added modules lazy and state
|
|
131
147
|
- renamed flatmap methods to bind
|
|
132
148
|
- minor MB and XOR updates/corrections
|
|
133
149
|
|
|
134
|
-
1.1.0 - 2024-11-18
|
|
135
|
-
|
|
150
|
+
PyPI 1.1.0 - 2024-11-18
|
|
151
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
136
152
|
|
|
137
153
|
Added fp.function module.
|
|
138
154
|
|
|
139
155
|
- combine and partially apply functions as first class objects
|
|
140
156
|
- some tests may be lacking
|
|
141
157
|
|
|
142
|
-
1.0.2.0 - 2024-10-20
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Development environment only.
|
|
158
|
+
Version 1.0.2.0 - 2024-10-20 (Devel environment only)
|
|
159
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
146
160
|
|
|
147
161
|
- breaking API changes, next PyPI release will be 1.1.0.
|
|
148
162
|
- renamed module ``nothingness`` to ``singletons``
|
|
@@ -158,16 +172,16 @@ Development environment only.
|
|
|
158
172
|
|
|
159
173
|
- will redo docs in docs repo
|
|
160
174
|
|
|
161
|
-
1.0.1 - 2024-10-20
|
|
162
|
-
|
|
175
|
+
PyPI 1.0.1 - 2024-10-20
|
|
176
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
163
177
|
|
|
164
178
|
- removed docs from repo
|
|
165
179
|
- docs for all grscheller namespace projects maintained here
|
|
166
180
|
|
|
167
181
|
- https://grscheller.github.io/grscheller-pypi-namespace-docs/
|
|
168
182
|
|
|
169
|
-
1.0.0 - 2024-10-18
|
|
170
|
-
|
|
183
|
+
PyPI 1.0.0 - 2024-10-18
|
|
184
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
171
185
|
|
|
172
186
|
Decided to make this release first stable release.
|
|
173
187
|
|
|
@@ -177,33 +191,31 @@ Decided to make this release first stable release.
|
|
|
177
191
|
|
|
178
192
|
- pytest improvements based on pytest documentation
|
|
179
193
|
|
|
180
|
-
0.4.0 - 2024-10-03
|
|
181
|
-
|
|
194
|
+
PyPI 0.4.0 - 2024-10-03
|
|
195
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
182
196
|
|
|
183
197
|
Long overdue PyPI release.
|
|
184
198
|
|
|
185
|
-
0.3.5.1 - 2024-10-03
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
Development environment only.
|
|
199
|
+
Version 0.3.5.1 - 2024-10-03 (Devel environment only)
|
|
200
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
189
201
|
|
|
190
|
-
|
|
202
|
+
New module ``grscheller.fp.nothingness`` which contains
|
|
191
203
|
|
|
192
|
-
|
|
204
|
+
- Singleton ``noValue`` representing a missing value
|
|
193
205
|
|
|
194
|
-
|
|
206
|
+
- similar to ``None`` but while
|
|
195
207
|
|
|
196
|
-
|
|
197
|
-
|
|
208
|
+
- ``None`` represent "returned no values"
|
|
209
|
+
- ``noValue: _NoValue = _NoValue()`` represents an absent value
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
- mostly used as an implementation detail
|
|
200
212
|
|
|
201
|
-
|
|
213
|
+
- allows client code to use ``None`` as a sentinel value
|
|
202
214
|
|
|
203
|
-
|
|
215
|
+
- prefer class ``MB`` to represent a missing value in client code
|
|
204
216
|
|
|
205
|
-
0.3.3 - 2024-08-25
|
|
206
|
-
|
|
217
|
+
PyPI 0.3.3 - 2024-08-25
|
|
218
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
207
219
|
|
|
208
220
|
- removed woException ``XOR`` method
|
|
209
221
|
|
|
@@ -214,23 +226,23 @@ Development environment only.
|
|
|
214
226
|
- makeRight(self, right: R|Nada=nada) -> XOR\[L, R\]:
|
|
215
227
|
- swapRight(self, right: R) -> XOR\[L, R\]:
|
|
216
228
|
|
|
217
|
-
0.3.0 - 2024-08-17
|
|
218
|
-
|
|
229
|
+
PyPI 0.3.0 - 2024-08-17
|
|
230
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
219
231
|
|
|
220
232
|
Class Nothing re-added but renamed class Nada.
|
|
221
233
|
|
|
222
234
|
Version grscheller.untyped.nothing for more strictly typed code.
|
|
223
235
|
|
|
224
|
-
0.2.1 - 2024-07-26
|
|
225
|
-
|
|
236
|
+
PyPI 0.2.1 - 2024-07-26
|
|
237
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
226
238
|
|
|
227
239
|
PyPI grscheller.fp package release v0.2.1
|
|
228
240
|
|
|
229
241
|
- forgot to update README.md on last PyPI release
|
|
230
242
|
- simplified README.md to help alleviate this mistake in the future
|
|
231
243
|
|
|
232
|
-
0.2.0 - 2024-07-26
|
|
233
|
-
|
|
244
|
+
PyPI 0.2.0 - 2024-07-26
|
|
245
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
234
246
|
|
|
235
247
|
- from last PyPI release
|
|
236
248
|
|
|
@@ -241,8 +253,8 @@ PyPI grscheller.fp package release v0.2.1
|
|
|
241
253
|
|
|
242
254
|
- renamed ``fp.wo_exception`` to ``fp.woException``
|
|
243
255
|
|
|
244
|
-
0.1.0 - 2024-07-11
|
|
245
|
-
|
|
256
|
+
PyPI 0.1.0 - 2024-07-11
|
|
257
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
246
258
|
|
|
247
259
|
Initial PyPI release as grscheller.fp
|
|
248
260
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonic-fp-fptools
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.2.0
|
|
4
4
|
Summary: Pythonic FP - Functional Programming Tools
|
|
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.12
|
|
8
8
|
Description-Content-Type: text/x-rst
|
|
9
|
-
Classifier: Development Status ::
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
10
|
Classifier: Framework :: Pytest
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -14,14 +14,16 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Classifier: Typing :: Typed
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: pythonic-fp-booleans>=
|
|
18
|
-
Requires-Dist: pythonic-fp-circulararray>=
|
|
19
|
-
Requires-Dist: pythonic-fp-
|
|
17
|
+
Requires-Dist: pythonic-fp-booleans>=2.1.1
|
|
18
|
+
Requires-Dist: pythonic-fp-circulararray>=6.0.1
|
|
19
|
+
Requires-Dist: pythonic-fp-gadgets>=4.0.2
|
|
20
20
|
Requires-Dist: pytest>=8.4.1 ; extra == "test"
|
|
21
|
-
Requires-Dist: pythonic-fp-containers>=
|
|
21
|
+
Requires-Dist: pythonic-fp-containers>=4.0.1 ; extra == "test"
|
|
22
|
+
Requires-Dist: pythonic-fp-iterables>=5.1.3 ; extra == "test"
|
|
23
|
+
Requires-Dist: pythonic-fp-queues>=5.1.1 ; extra == "test"
|
|
22
24
|
Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-fptools/blob/main/CHANGELOG.rst
|
|
23
|
-
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/fptools/development/build/html/
|
|
24
|
-
Project-URL: Homepage, https://github.
|
|
25
|
+
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/fptools/development/build/html/
|
|
26
|
+
Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/build/html/
|
|
25
27
|
Project-URL: Source, https://github.com/grscheller/pythonic-fp-fptools
|
|
26
28
|
Provides-Extra: test
|
|
27
29
|
|
|
@@ -49,16 +51,17 @@ endeavoring to be Pythonic.
|
|
|
49
51
|
|
|
50
52
|
- the monad encapsulates a state transformation, not a "state"
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
`pythonic-fp
|
|
54
|
-
<https://github.
|
|
54
|
+
Part of the
|
|
55
|
+
`pythonic-fp
|
|
56
|
+
<https://grscheller.github.io/pythonic-fp>`_
|
|
57
|
+
PyPI projects.
|
|
55
58
|
|
|
56
59
|
Documentation
|
|
57
60
|
-------------
|
|
58
61
|
|
|
59
62
|
Documentation for this project is hosted on
|
|
60
63
|
`GitHub Pages
|
|
61
|
-
<https://grscheller.github.io/pythonic-fp/fptools
|
|
64
|
+
<https://grscheller.github.io/pythonic-fp/fptools>`_.
|
|
62
65
|
|
|
63
66
|
Copyright and License
|
|
64
67
|
---------------------
|
|
@@ -22,16 +22,17 @@ endeavoring to be Pythonic.
|
|
|
22
22
|
|
|
23
23
|
- the monad encapsulates a state transformation, not a "state"
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
`pythonic-fp
|
|
27
|
-
<https://github.
|
|
25
|
+
Part of the
|
|
26
|
+
`pythonic-fp
|
|
27
|
+
<https://grscheller.github.io/pythonic-fp>`_
|
|
28
|
+
PyPI projects.
|
|
28
29
|
|
|
29
30
|
Documentation
|
|
30
31
|
-------------
|
|
31
32
|
|
|
32
33
|
Documentation for this project is hosted on
|
|
33
34
|
`GitHub Pages
|
|
34
|
-
<https://grscheller.github.io/pythonic-fp/fptools
|
|
35
|
+
<https://grscheller.github.io/pythonic-fp/fptools>`_.
|
|
35
36
|
|
|
36
37
|
Copyright and License
|
|
37
38
|
---------------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pythonic-fp-fptools"
|
|
3
|
-
version = "5.
|
|
3
|
+
version = "5.2.0"
|
|
4
4
|
readme = "README.rst"
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -16,7 +16,7 @@ keywords = [
|
|
|
16
16
|
"non-strict",
|
|
17
17
|
]
|
|
18
18
|
classifiers = [
|
|
19
|
-
"Development Status ::
|
|
19
|
+
"Development Status :: 4 - Beta",
|
|
20
20
|
"Framework :: Pytest",
|
|
21
21
|
"Intended Audience :: Developers",
|
|
22
22
|
"License :: OSI Approved :: Apache Software License",
|
|
@@ -25,22 +25,24 @@ classifiers = [
|
|
|
25
25
|
"Typing :: Typed",
|
|
26
26
|
]
|
|
27
27
|
dependencies = [
|
|
28
|
-
"pythonic-fp-booleans>=
|
|
29
|
-
"pythonic-fp-circulararray>=
|
|
30
|
-
"pythonic-fp-
|
|
28
|
+
"pythonic-fp-booleans>=2.1.1",
|
|
29
|
+
"pythonic-fp-circulararray>=6.0.1",
|
|
30
|
+
"pythonic-fp-gadgets>=4.0.2",
|
|
31
31
|
]
|
|
32
32
|
dynamic = ["description"]
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
35
|
Changelog = "https://github.com/grscheller/pythonic-fp-fptools/blob/main/CHANGELOG.rst"
|
|
36
|
-
Documentation = "https://grscheller.github.io/pythonic-fp/fptools/development/build/html/
|
|
37
|
-
Homepage = "https://github.
|
|
36
|
+
Documentation = "https://grscheller.github.io/pythonic-fp/fptools/development/build/html/"
|
|
37
|
+
Homepage = "https://grscheller.github.io/pythonic-fp/homepage/build/html/"
|
|
38
38
|
Source = "https://github.com/grscheller/pythonic-fp-fptools"
|
|
39
39
|
|
|
40
40
|
[project.optional-dependencies]
|
|
41
41
|
test = [
|
|
42
42
|
"pytest>=8.4.1",
|
|
43
|
-
"pythonic-fp-containers>=
|
|
43
|
+
"pythonic-fp-containers>=4.0.1",
|
|
44
|
+
"pythonic-fp-iterables>=5.1.3",
|
|
45
|
+
"pythonic-fp-queues>=5.1.1",
|
|
44
46
|
]
|
|
45
47
|
|
|
46
48
|
[build-system]
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
__all__ = ['Either', 'LEFT', 'RIGHT']
|
|
15
|
+
__all__ = ['Either', 'EitherBool', 'LEFT', 'RIGHT']
|
|
16
16
|
|
|
17
17
|
from collections.abc import Callable, Iterator, Sequence
|
|
18
18
|
from typing import cast, overload
|
|
@@ -21,6 +21,12 @@ from .maybe import MayBe
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class EitherBool(SBool):
|
|
24
|
+
"""Boolean-like type used by Either constructor.
|
|
25
|
+
|
|
26
|
+
- A "truthy" value passed to constructor produces the unique ``LEFT`` value.
|
|
27
|
+
- A "falsy" value passed to constructor produces the unique ``RIGHT`` value.
|
|
28
|
+
|
|
29
|
+
"""
|
|
24
30
|
def __repr__(self) -> str:
|
|
25
31
|
if self:
|
|
26
32
|
return 'LEFT'
|
|
@@ -28,36 +34,38 @@ class EitherBool(SBool):
|
|
|
28
34
|
|
|
29
35
|
|
|
30
36
|
LEFT = EitherBool(True)
|
|
37
|
+
"""Singleton value signaling ``Either`` constructor to produce a ``LEFT`` Either, the default."""
|
|
38
|
+
|
|
31
39
|
RIGHT = EitherBool(False)
|
|
40
|
+
"""Singleton value signaling ``Either`` constructor to produce a ``RIGHT`` Either."""
|
|
32
41
|
|
|
33
42
|
|
|
34
43
|
class Either[L, R]:
|
|
35
44
|
"""
|
|
36
|
-
Either Monad
|
|
37
|
-
------------
|
|
45
|
+
.. admonition:: Either Monad
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
Data structure semantically containing either a left
|
|
48
|
+
or a right value, but not both.
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
Implements a left biased Either Monad.
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
- ``Either(value: +L, LEFT)`` produces a left ``Either``
|
|
53
|
+
- ``Either(value: +L, RIGHT)`` produces a right ``Either``
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
In a Boolean context
|
|
48
56
|
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
- A left ``Either`` is "truthy"
|
|
58
|
+
- A right ``Either`` is "falsy"
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
Two ``Either`` objects compare as equal when
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
- both are left values or both are right values whose values
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
- are the same object
|
|
65
|
+
- compare as equal
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
Immutable, an ``Either`` does not change after being created.
|
|
68
|
+
Therefore ``map`` & ``bind`` return new instances.
|
|
61
69
|
|
|
62
70
|
.. warning::
|
|
63
71
|
|
|
@@ -4,7 +4,7 @@ from collections.abc import Callable, Iterator, Sequence
|
|
|
4
4
|
from pythonic_fp.booleans.subtypable import SBool
|
|
5
5
|
from typing import overload
|
|
6
6
|
|
|
7
|
-
__all__ = ['Either', 'LEFT', 'RIGHT']
|
|
7
|
+
__all__ = ['Either', 'EitherBool', 'LEFT', 'RIGHT']
|
|
8
8
|
|
|
9
9
|
class EitherBool(SBool): ...
|
|
10
10
|
|
|
@@ -13,32 +13,28 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""
|
|
16
|
-
FP tools for functions
|
|
17
|
-
======================
|
|
16
|
+
.. admonition:: FP tools for functions
|
|
18
17
|
|
|
19
|
-
FP utilities to manipulate and partially apply functions
|
|
18
|
+
FP utilities to manipulate and partially apply functions.
|
|
20
19
|
|
|
21
|
-
- *function* **swap** - Swap the arguments of a 2 argument function
|
|
22
|
-
- *function* **
|
|
23
|
-
- *function* **negate** - Transforms a predicate to its negation
|
|
24
|
-
- *function* **
|
|
20
|
+
- *function* **swap** - Swap the arguments of a 2 argument function
|
|
21
|
+
- *function* **compose** - Function composition
|
|
22
|
+
- *function* **negate** - Transforms a predicate to its negation
|
|
23
|
+
- *function* **sequenced** - Convert function to take a sequence of its arguments
|
|
24
|
+
- *function* **partial** - Returns a partially applied function
|
|
25
25
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
from collections.abc import Callable
|
|
29
29
|
from typing import Any, ParamSpec
|
|
30
30
|
|
|
31
|
-
__all__ = ['swap', '
|
|
31
|
+
__all__ = ['swap', 'compose', 'negate', 'sequenced', 'partial']
|
|
32
32
|
|
|
33
33
|
P = ParamSpec('P')
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def swap[U, V, R](f: Callable[[U, V], R]) -> Callable[[V, U], R]:
|
|
37
|
-
"""
|
|
38
|
-
Swap args
|
|
39
|
-
---------
|
|
40
|
-
|
|
41
|
-
Swap arguments of a two argument function.
|
|
37
|
+
"""Swap arguments of a two argument function.
|
|
42
38
|
|
|
43
39
|
:param f: Two argument function.
|
|
44
40
|
:returns: A version of ``f`` with its arguments swapped.
|
|
@@ -47,17 +43,23 @@ def swap[U, V, R](f: Callable[[U, V], R]) -> Callable[[V, U], R]:
|
|
|
47
43
|
return lambda v, u: f(u, v)
|
|
48
44
|
|
|
49
45
|
|
|
50
|
-
def
|
|
46
|
+
def compose[D, T, R](f: Callable[[D], T], g: Callable[[T], R]) -> Callable[[D], R]:
|
|
47
|
+
"""Function Composition
|
|
48
|
+
|
|
49
|
+
:param f: Function called first with domain D and range T.
|
|
50
|
+
:param g: Function called on result with domain T and range R.
|
|
51
|
+
:returns: The composite function g∘f(d) = g(f(d))
|
|
52
|
+
|
|
51
53
|
"""
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
return lambda d: g(f(d))
|
|
55
|
+
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
def negate[**P](f: Callable[P, bool]) -> Callable[P, bool]:
|
|
58
|
+
"""Take a predicate and return its negation.
|
|
56
59
|
|
|
57
60
|
:param f: a function ``f`` which returns a bool
|
|
58
61
|
:returns: the function ``not f``
|
|
59
62
|
"""
|
|
60
|
-
|
|
61
63
|
def ff(*args: P.args, **kwargs: P.kwargs) -> bool:
|
|
62
64
|
return not f(*args, **kwargs)
|
|
63
65
|
|
|
@@ -65,9 +67,7 @@ def negate[**P](f: Callable[P, bool]) -> Callable[P, bool]:
|
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
def sequenced[R](f: Callable[..., R]) -> Callable[[tuple[Any]], R]:
|
|
68
|
-
"""
|
|
69
|
-
Multi-to-single valued
|
|
70
|
-
----------------------
|
|
70
|
+
"""Convert a function from multi-to-single valued.
|
|
71
71
|
|
|
72
72
|
Convert a function with arbitrary positional arguments to one taking
|
|
73
73
|
a tuple of the original arguments.
|
|
@@ -80,7 +80,6 @@ def sequenced[R](f: Callable[..., R]) -> Callable[[tuple[Any]], R]:
|
|
|
80
80
|
TODO: Look into replacing this function with a Callable class?
|
|
81
81
|
|
|
82
82
|
"""
|
|
83
|
-
|
|
84
83
|
def ff(tupled_args: tuple[Any]) -> R:
|
|
85
84
|
return f(*tupled_args)
|
|
86
85
|
|
|
@@ -88,9 +87,7 @@ def sequenced[R](f: Callable[..., R]) -> Callable[[tuple[Any]], R]:
|
|
|
88
87
|
|
|
89
88
|
|
|
90
89
|
def partial[**P, R](f: Callable[P, R], *args: Any) -> Callable[..., R]:
|
|
91
|
-
"""
|
|
92
|
-
Partial application
|
|
93
|
-
-------------------
|
|
90
|
+
"""Partial function application.
|
|
94
91
|
|
|
95
92
|
Partially apply arguments to a function, left to right.
|
|
96
93
|
|
|
@@ -98,7 +95,6 @@ def partial[**P, R](f: Callable[P, R], *args: Any) -> Callable[..., R]:
|
|
|
98
95
|
- best practice is to cast the result immediately
|
|
99
96
|
|
|
100
97
|
"""
|
|
101
|
-
|
|
102
98
|
def finish(*rest: Any) -> R:
|
|
103
99
|
return sequenced(f)(args + rest)
|
|
104
100
|
|
{pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/src/pythonic_fp/fptools/function.pyi
RENAMED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
from typing import Any, ParamSpec
|
|
3
3
|
|
|
4
|
-
__all__ = ['swap', '
|
|
4
|
+
__all__ = ['swap', 'compose', 'negate', 'sequenced', 'partial']
|
|
5
5
|
|
|
6
6
|
P = ParamSpec('P')
|
|
7
7
|
|
|
8
8
|
def swap[U, V, R](f: Callable[[U, V], R]) -> Callable[[V, U], R]: ...
|
|
9
|
+
def compose[D, T, R](f: Callable[[D], T], g: Callable[[T], R]) -> Callable[[D], R]: ...
|
|
9
10
|
def negate[**P](f: Callable[P, bool]) -> Callable[P, bool]: ...
|
|
10
11
|
def sequenced[R](f: Callable[..., R]) -> Callable[[tuple[Any]], R]: ...
|
|
11
12
|
def partial[**P, R](f: Callable[P, R], *args: Any) -> Callable[..., R]: ...
|
|
@@ -13,17 +13,16 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""
|
|
16
|
-
Lazy function evaluation
|
|
17
|
-
========================
|
|
16
|
+
.. admonition:: Lazy function evaluation
|
|
18
17
|
|
|
19
|
-
Delayed function evaluations. FP tools for "non-strict" function evaluations.
|
|
20
|
-
Useful to delay a function's evaluation until some inner scope.
|
|
18
|
+
Delayed function evaluations. FP tools for "non-strict" function evaluations.
|
|
19
|
+
Useful to delay a function's evaluation until some inner scope.
|
|
21
20
|
|
|
22
|
-
Non-strict delayed function evaluation.
|
|
21
|
+
Non-strict delayed function evaluation.
|
|
23
22
|
|
|
24
|
-
- *class* **Lazy** - Delay evaluation of functions taking & returning single values
|
|
25
|
-
- *function* **lazy** - Delay evaluation of functions taking any number of values
|
|
26
|
-
- *function* **real_lazy** - Version of ``lazy`` which caches its result
|
|
23
|
+
- *class* **Lazy** - Delay evaluation of functions taking & returning single values
|
|
24
|
+
- *function* **lazy** - Delay evaluation of functions taking any number of values
|
|
25
|
+
- *function* **real_lazy** - Version of ``lazy`` which caches its result
|
|
27
26
|
|
|
28
27
|
"""
|
|
29
28
|
|
|
@@ -38,14 +37,13 @@ __all__ = ['Lazy', 'lazy', 'real_lazy']
|
|
|
38
37
|
|
|
39
38
|
class Lazy[D, R]:
|
|
40
39
|
"""
|
|
41
|
-
Non-strict function evaluation
|
|
42
|
-
------------------------------
|
|
40
|
+
.. admonition:: Non-strict function evaluation
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
Delayed evaluation of a singled valued function.
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
Class instance delays the executable of a function where ``Lazy(f, arg)``
|
|
45
|
+
constructs an object that can evaluate the Callable ``f`` with its argument
|
|
46
|
+
at a later time.
|
|
49
47
|
|
|
50
48
|
.. note::
|
|
51
49
|
|
|
@@ -153,11 +151,10 @@ def lazy[**P, R](
|
|
|
153
151
|
f: Callable[P, R], *args: P.args, **kwargs: P.kwargs
|
|
154
152
|
) -> Lazy[tuple[Any, ...], R]:
|
|
155
153
|
"""
|
|
156
|
-
Delayed evaluations
|
|
157
|
-
-------------------
|
|
154
|
+
.. admonition:: Delayed evaluations
|
|
158
155
|
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
Function returning a delayed evaluation of a function of an arbitrary number
|
|
157
|
+
of positional arguments.
|
|
161
158
|
|
|
162
159
|
:param f: Function whose evaluation is to be delayed.
|
|
163
160
|
:param args: Positional arguments to be passed to ``f``.
|
|
@@ -172,11 +169,10 @@ def real_lazy[**P, R](
|
|
|
172
169
|
f: Callable[P, R], *args: P.args, **kwargs: P.kwargs
|
|
173
170
|
) -> Lazy[tuple[Any, ...], R]:
|
|
174
171
|
"""
|
|
175
|
-
Cached Delayed evaluations
|
|
176
|
-
--------------------------
|
|
172
|
+
.. admonition:: Cached Delayed evaluations
|
|
177
173
|
|
|
178
|
-
|
|
179
|
-
|
|
174
|
+
Function returning a delayed evaluation of a function of an
|
|
175
|
+
arbitrary number of positional arguments. Evaluation is cached.
|
|
180
176
|
|
|
181
177
|
:param f: Function whose evaluation is to be delayed.
|
|
182
178
|
:param args: Positional arguments to be passed to ``f``.
|
|
@@ -18,23 +18,22 @@ __all__ = ['MayBe']
|
|
|
18
18
|
|
|
19
19
|
from collections.abc import Callable, Iterator, Sequence
|
|
20
20
|
from typing import cast, Final, overload
|
|
21
|
-
from pythonic_fp.sentinels.flavored import Sentinel
|
|
21
|
+
from pythonic_fp.gadgets.sentinels.flavored import Sentinel
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class MayBe[D]:
|
|
25
25
|
"""
|
|
26
|
-
Maybe Monad
|
|
27
|
-
-----------
|
|
26
|
+
.. admonition:: Maybe Monad
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
Data structure wrapping a potentially missing item.
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
Immutable semantics
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
- can store any item of any type, including ``None``
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
- with one hidden implementation dependent exception
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
- immutable semantics
|
|
38
37
|
|
|
39
38
|
.. warning::
|
|
40
39
|
|
|
File without changes
|
|
@@ -20,17 +20,16 @@ from pythonic_fp.circulararray.auto import CA
|
|
|
20
20
|
|
|
21
21
|
class State[S, A]:
|
|
22
22
|
"""
|
|
23
|
-
State Monad
|
|
24
|
-
-----------
|
|
23
|
+
.. admonition:: State Monad
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Data structure generating values while propagating changes of state.
|
|
26
|
+
A pure FP implementation for the State Monad
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
- class ``State`` represents neither a state nor a (value, state) pair
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
- it wraps a transformation old_state -> (value, new_state)
|
|
31
|
+
- the ``run`` method is this wrapped transformation
|
|
32
|
+
- ``bind`` is just state propagating function composition
|
|
34
33
|
|
|
35
34
|
"""
|
|
36
35
|
|
{pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/either/test_sequence_either.py
RENAMED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from typing import Final
|
|
16
16
|
from pythonic_fp.containers.functional_tuple import FTuple
|
|
17
17
|
from pythonic_fp.fptools.either import Either, LEFT, RIGHT
|
|
18
|
-
from pythonic_fp.
|
|
18
|
+
from pythonic_fp.queues.fifo import FIFOQueue
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class TestEitherSequence:
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from pythonic_fp.containers.functional_tuple import FTuple
|
|
16
16
|
from pythonic_fp.fptools.maybe import MayBe
|
|
17
|
-
from pythonic_fp.
|
|
17
|
+
from pythonic_fp.queues.de import DEQueue, de_queue
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class Test_MB_sequence:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonic_fp_fptools-5.1.1 → pythonic_fp_fptools-5.2.0}/tests/either/test_str_repr_either.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|