Skip to content

Commit b2888f2

Browse files
authored
Adds swappable (#681)
* Adds swappable * Fixes CI
1 parent 6ae689a commit b2888f2

File tree

13 files changed

+169
-99
lines changed

13 files changed

+169
-99
lines changed

docs/pages/create-your-own-container.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ let's find pre-defined aliases we can reuse.
7474
Turns out, there are some of them!
7575

7676
- :class:`returns.interfaces.bimappable.BiMappableN`
77-
which combines ``MappableN`` and ``AltableN``,
78-
it also requires to add a new method called ``.swap`` to change values order
77+
which combines ``MappableN`` and ``AltableN``
78+
- :class:`returns.interfaces.swappable.SwappableN`
79+
is an alias for ``BiMappableN``
80+
with a new method called ``.swap`` to change values order
7981

8082
Let's look at the resul:
8183

@@ -84,7 +86,7 @@ Let's look at the resul:
8486
>>> from typing_extensions import final
8587
>>> from typing import Callable, TypeVar, Tuple
8688
87-
>>> from returns.interfaces import bimappable, bindable, equable, lashable
89+
>>> from returns.interfaces import bindable, equable, lashable, swappable
8890
>>> from returns.primitives.container import BaseContainer
8991
>>> from returns.primitives.hkt import SupportsKind2
9092
@@ -99,7 +101,7 @@ Let's look at the resul:
99101
... BaseContainer,
100102
... SupportsKind2['Pair', _FirstType, _SecondType],
101103
... bindable.Bindable2[_FirstType, _SecondType],
102-
... bimappable.BiMappable2[_FirstType, _SecondType],
104+
... swappable.Swappable2[_FirstType, _SecondType],
103105
... lashable.Lashable2[_FirstType, _SecondType],
104106
... equable.Equable,
105107
... ):

docs/pages/interfaces.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,16 @@ BiMappable
528528
:members:
529529
:private-members:
530530

531+
Swappable
532+
~~~~~~~~~
533+
534+
.. autoclasstree:: returns.interfaces.swappable
535+
:strict:
536+
537+
.. automodule:: returns.interfaces.swappable
538+
:members:
539+
:private-members:
540+
531541
Lashable
532542
~~~~~~~~
533543

returns/interfaces/bimappable.py

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,15 @@
1-
from abc import abstractmethod
2-
from typing import ClassVar, NoReturn, Sequence, TypeVar
3-
4-
from typing_extensions import final
1+
from typing import NoReturn, TypeVar
52

63
from returns.interfaces import altable, mappable
7-
from returns.primitives.asserts import assert_equal
8-
from returns.primitives.hkt import KindN
9-
from returns.primitives.laws import (
10-
Law,
11-
Law1,
12-
Lawful,
13-
LawSpecDef,
14-
law_definition,
15-
)
164

175
_FirstType = TypeVar('_FirstType')
186
_SecondType = TypeVar('_SecondType')
197
_ThirdType = TypeVar('_ThirdType')
208

21-
_BiMappableType = TypeVar('_BiMappableType', bound='BiMappableN')
22-
23-
24-
@final
25-
class _LawSpec(LawSpecDef):
26-
"""Laws for :class:`~BiMappableN` type."""
27-
28-
@law_definition
29-
def double_swap_law(
30-
container: 'BiMappableN[_FirstType, _SecondType, _ThirdType]',
31-
) -> None:
32-
"""
33-
Swaaping container twice.
34-
35-
It ensure that we get the initial value back.
36-
In other words, swapping twice does nothing.
37-
"""
38-
assert_equal(
39-
container,
40-
container.swap().swap(),
41-
)
42-
439

4410
class BiMappableN(
4511
mappable.MappableN[_FirstType, _SecondType, _ThirdType],
4612
altable.AltableN[_FirstType, _SecondType, _ThirdType],
47-
Lawful['BiMappableN[_FirstType, _SecondType, _ThirdType]'],
4813
):
4914
"""
5015
Allows to change both types of a container at the same time.
@@ -56,16 +21,6 @@ class BiMappableN(
5621
5722
"""
5823

59-
_laws: ClassVar[Sequence[Law]] = (
60-
Law1(_LawSpec.double_swap_law),
61-
)
62-
63-
@abstractmethod
64-
def swap(
65-
self: _BiMappableType,
66-
) -> KindN[_BiMappableType, _SecondType, _FirstType, _ThirdType]:
67-
"""Swaps first and second types in ``BiMappableN``."""
68-
6924

7025
#: Type alias for kinds with two type arguments.
7126
BiMappable2 = BiMappableN[_FirstType, _SecondType, NoReturn]

returns/interfaces/failable.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33

44
from typing_extensions import final
55

6-
from returns.interfaces.bimappable import BiMappableN
7-
from returns.interfaces.container import ContainerN
8-
from returns.interfaces.lashable import LashableN
6+
from returns.interfaces import container as _container
7+
from returns.interfaces import lashable, swappable
98
from returns.primitives.asserts import assert_equal
109
from returns.primitives.hkt import KindN
1110
from returns.primitives.laws import (
@@ -55,8 +54,8 @@ def lash_short_circuit_law(
5554

5655

5756
class FailableN(
58-
ContainerN[_FirstType, _SecondType, _ThirdType],
59-
LashableN[_FirstType, _SecondType, _ThirdType],
57+
_container.ContainerN[_FirstType, _SecondType, _ThirdType],
58+
lashable.LashableN[_FirstType, _SecondType, _ThirdType],
6059
Lawful['FailableN[_FirstType, _SecondType, _ThirdType]'],
6160
):
6261
"""
@@ -223,7 +222,7 @@ def alt_short_circuit_law(
223222

224223
class DiverseFailableN(
225224
FailableN[_FirstType, _SecondType, _ThirdType],
226-
BiMappableN[_FirstType, _SecondType, _ThirdType],
225+
swappable.SwappableN[_FirstType, _SecondType, _ThirdType],
227226
Lawful['DiverseFailableN[_FirstType, _SecondType, _ThirdType]'],
228227
):
229228
"""

returns/interfaces/swappable.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from abc import abstractmethod
2+
from typing import ClassVar, NoReturn, Sequence, TypeVar
3+
4+
from typing_extensions import final
5+
6+
from returns.interfaces import bimappable
7+
from returns.primitives.asserts import assert_equal
8+
from returns.primitives.hkt import KindN
9+
from returns.primitives.laws import (
10+
Law,
11+
Law1,
12+
Lawful,
13+
LawSpecDef,
14+
law_definition,
15+
)
16+
17+
_FirstType = TypeVar('_FirstType')
18+
_SecondType = TypeVar('_SecondType')
19+
_ThirdType = TypeVar('_ThirdType')
20+
21+
_SwappableType = TypeVar('_SwappableType', bound='SwappableN')
22+
23+
24+
@final
25+
class _LawSpec(LawSpecDef):
26+
"""Laws for :class:`~SwappableN` type."""
27+
28+
@law_definition
29+
def double_swap_law(
30+
container: 'SwappableN[_FirstType, _SecondType, _ThirdType]',
31+
) -> None:
32+
"""
33+
Swaaping container twice.
34+
35+
It ensure that we get the initial value back.
36+
In other words, swapping twice does nothing.
37+
"""
38+
assert_equal(
39+
container,
40+
container.swap().swap(),
41+
)
42+
43+
44+
class SwappableN(
45+
bimappable.BiMappableN[_FirstType, _SecondType, _ThirdType],
46+
Lawful['SwappableN[_FirstType, _SecondType, _ThirdType]'],
47+
):
48+
"""Interface that allows swapping first and second type values."""
49+
50+
_laws: ClassVar[Sequence[Law]] = (
51+
Law1(_LawSpec.double_swap_law),
52+
)
53+
54+
@abstractmethod
55+
def swap(
56+
self: _SwappableType,
57+
) -> KindN[_SwappableType, _SecondType, _FirstType, _ThirdType]:
58+
"""Swaps first and second types in ``SwappableN``."""
59+
60+
61+
#: Type alias for kinds with two type arguments.
62+
Swappable2 = SwappableN[_FirstType, _SecondType, NoReturn]
63+
64+
#: Type alias for kinds with three type arguments.
65+
Swappable3 = SwappableN[_FirstType, _SecondType, _ThirdType]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ i-control-code = False
2222

2323
extend-exclude =
2424
.venv
25+
build
2526
# Bad code that I write to test things:
2627
ex.py
2728
experiments

tests/test_examples/test_pair1.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing_extensions import final
44

5-
from returns.interfaces import bimappable, bindable, equable, lashable
5+
from returns.interfaces import bindable, equable, lashable, swappable
66
from returns.primitives.container import BaseContainer, container_equality
77
from returns.primitives.hkt import Kind2, SupportsKind2, dekind
88

@@ -18,7 +18,7 @@ class Pair(
1818
BaseContainer,
1919
SupportsKind2['Pair', _FirstType, _SecondType],
2020
bindable.Bindable2[_FirstType, _SecondType],
21-
bimappable.BiMappable2[_FirstType, _SecondType],
21+
swappable.Swappable2[_FirstType, _SecondType],
2222
lashable.Lashable2[_FirstType, _SecondType],
2323
equable.Equable,
2424
):
@@ -79,7 +79,7 @@ def lash(
7979
) -> 'Pair[_FirstType, _NewSecondType]':
8080
return dekind(function(self._inner_value[1]))
8181

82-
# `BiMappableN` part:
82+
# `SwappableN` part:
8383

8484
def swap(self) -> 'Pair[_SecondType, _FirstType]':
8585
return Pair((self._inner_value[1], self._inner_value[0]))

tests/test_examples/test_pair2.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from typing_extensions import final
55

6-
from returns.interfaces import bimappable, bindable, equable, lashable
6+
from returns.interfaces import bindable, equable, lashable, swappable
77
from returns.primitives.container import BaseContainer, container_equality
88
from returns.primitives.hkt import Kind2, KindN, SupportsKind2, dekind
99

@@ -19,7 +19,7 @@
1919

2020
class PairLikeN(
2121
bindable.BindableN[_FirstType, _SecondType, _ThirdType],
22-
bimappable.BiMappableN[_FirstType, _SecondType, _ThirdType],
22+
swappable.SwappableN[_FirstType, _SecondType, _ThirdType],
2323
lashable.LashableN[_FirstType, _SecondType, _ThirdType],
2424
equable.Equable,
2525
):
@@ -122,7 +122,7 @@ def lash(
122122
) -> 'Pair[_FirstType, _NewSecondType]':
123123
return dekind(function(self._inner_value[1]))
124124

125-
# `BiMappableN` part:
125+
# `SwappableN` part:
126126

127127
def swap(self) -> 'Pair[_SecondType, _FirstType]':
128128
return Pair((self._inner_value[1], self._inner_value[0]))

tests/test_examples/test_pair3.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from typing_extensions import final
55

6-
from returns.interfaces import bimappable, bindable, equable, lashable
6+
from returns.interfaces import bindable, equable, lashable, swappable
77
from returns.primitives.container import BaseContainer, container_equality
88
from returns.primitives.hkt import Kind2, KindN, SupportsKind2, dekind
99

@@ -19,7 +19,7 @@
1919

2020
class PairLikeN(
2121
bindable.BindableN[_FirstType, _SecondType, _ThirdType],
22-
bimappable.BiMappableN[_FirstType, _SecondType, _ThirdType],
22+
swappable.SwappableN[_FirstType, _SecondType, _ThirdType],
2323
lashable.LashableN[_FirstType, _SecondType, _ThirdType],
2424
equable.Equable,
2525
):
@@ -150,7 +150,7 @@ def lash(
150150
"""
151151
return dekind(function(self._inner_value[1]))
152152

153-
# `BiMappableN` part:
153+
# `SwappableN` part:
154154

155155
def swap(self) -> 'Pair[_SecondType, _FirstType]':
156156
"""

tests/test_examples/test_pair4.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing_extensions import final
55

66
from returns.contrib.hypothesis.laws import check_all_laws
7-
from returns.interfaces import bimappable, bindable, equable, lashable
7+
from returns.interfaces import bindable, equable, lashable, swappable
88
from returns.primitives.asserts import assert_equal
99
from returns.primitives.container import BaseContainer, container_equality
1010
from returns.primitives.hkt import Kind2, KindN, SupportsKind2, dekind
@@ -50,7 +50,7 @@ def pair_left_identity_law(
5050

5151
class PairLikeN(
5252
bindable.BindableN[_FirstType, _SecondType, _ThirdType],
53-
bimappable.BiMappableN[_FirstType, _SecondType, _ThirdType],
53+
swappable.SwappableN[_FirstType, _SecondType, _ThirdType],
5454
lashable.LashableN[_FirstType, _SecondType, _ThirdType],
5555
equable.Equable,
5656
):
@@ -186,7 +186,7 @@ def lash(
186186
"""
187187
return dekind(function(self._inner_value[1]))
188188

189-
# `BiMappableN` part:
189+
# `SwappableN` part:
190190

191191
def swap(self) -> 'Pair[_SecondType, _FirstType]':
192192
"""

0 commit comments

Comments
 (0)