24
24
IDENTITY + 10 # 10
25
25
'hello' + IDENTITY # 'hello'
26
26
27
- class Max(Monoid[int]):
28
- def addition_operation(self, other: typing.Self) -> typing.Self:
29
- return Max(max(self.value, other.value))
30
-
31
- @staticmethod
32
- def identity_element() -> "Max":
33
- return _MinusInf()
34
-
35
- class _MinusInf(_MonoidIdentity, Max):
36
- pass
37
-
38
27
"""
39
28
40
29
from typing import (
@@ -59,10 +48,22 @@ class Monoid[T]:
59
48
60
49
"""
61
50
51
+ @classmethod
52
+ def wrap (cls , value : T ) -> Self :
53
+ if value == None :
54
+ return cls .identity_element ()
55
+ return cls (value )
56
+
62
57
def __init__ (self , value : T ) -> None :
58
+ if value == None :
59
+ raise ValueError ("None Objects not allowed in Monoids" )
63
60
self .value = value
64
61
65
- def __add__ (self , other : Self ) -> Self :
62
+ def __add__ (self , other : Self | T ) -> Self :
63
+ if not isinstance (other , self .__class__ ):
64
+ if isinstance (other , Monoid ):
65
+ raise ValueError ("Incompatible Monoid" )
66
+ return self .addition_operation (self .__class__ (other ))
66
67
return self .addition_operation (other )
67
68
68
69
def __eq__ (
@@ -93,21 +94,41 @@ def addition_operation(self: Self, other: Self) -> Self:
93
94
def identity_element [a : "Monoid" ](cls : type [a ]) -> a :
94
95
"""Returns the identity value for the monoid type.
95
96
96
- This method must be overridden in subclasses of Monoid.
97
+ This method must be overridden in subclasses of Monoid
97
98
98
99
"""
99
100
raise NotImplementedError
100
101
101
102
102
103
# class _MonoidIdentity[a : Monoid](a): #once Python Types has those features, this is what we want
103
- class _MonoidIdentity (Monoid ):
104
+ class _MonoidIdentity [T ](Monoid [T ]):
105
+ superclass = Monoid
106
+
104
107
def __init__ (self ):
108
+ found = False
109
+ for i in type (self ).__mro__ :
110
+ if (
111
+ i != _MonoidIdentity
112
+ and i != self .__class__
113
+ and i != Monoid
114
+ and i != Generic
115
+ and i != object
116
+ ):
117
+ self .superclass = i
118
+ found = True
119
+ break
120
+ if not found and self .__class__ != _MonoidIdentity :
121
+ raise Exception ("no superclass found" )
105
122
self .value = None
106
123
107
- def __add__ (self , other : Self ):
124
+ def __add__ (self : Self , other : Monoid [T ] | T ):
125
+ if not isinstance (other , Monoid ):
126
+ return self .superclass (other )
108
127
return other
109
128
110
129
def __radd__ (self , other : Self ):
130
+ if not isinstance (other , Monoid ):
131
+ return self .superclass (other )
111
132
return other
112
133
113
134
def __repr__ (self ):
@@ -117,11 +138,11 @@ def __repr__(self):
117
138
IDENTITY = _MonoidIdentity ()
118
139
119
140
120
- # allows: mconcat([Monoida, Monoidb]) #Bad
141
+ # mconcat([Monoida, Monoidb]) not throws an error :nice
121
142
def mconcat [a : Monoid ](monoid_list : Iterable [a ]) -> a :
122
143
"""Takes a list of monoid values and reduces them to a single value
123
144
by applying the '+' operation to all elements of the list.
124
- Needs a non empty list, because Python doesn't allow calling classMethods on types yet
145
+ Needs a non empty list, because Python doesn't allow calling on types
125
146
"""
126
147
it = monoid_list .__iter__ ()
127
148
0 commit comments