Skip to content

Commit 508fe72

Browse files
authoredDec 2, 2023
Added consumption of values
so Max(5) +7 = Max(7) Max(4) + "test" -> Error (cant compare int to string) Also Added checks for addition with different monoid
1 parent 984887e commit 508fe72

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed
 

‎pymonad/monoid.py

+38-17
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,6 @@
2424
IDENTITY + 10 # 10
2525
'hello' + IDENTITY # 'hello'
2626
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-
3827
"""
3928

4029
from typing import (
@@ -59,10 +48,22 @@ class Monoid[T]:
5948
6049
"""
6150

51+
@classmethod
52+
def wrap(cls, value: T) -> Self:
53+
if value == None:
54+
return cls.identity_element()
55+
return cls(value)
56+
6257
def __init__(self, value: T) -> None:
58+
if value == None:
59+
raise ValueError("None Objects not allowed in Monoids")
6360
self.value = value
6461

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))
6667
return self.addition_operation(other)
6768

6869
def __eq__(
@@ -93,21 +94,41 @@ def addition_operation(self: Self, other: Self) -> Self:
9394
def identity_element[a: "Monoid"](cls: type[a]) -> a:
9495
"""Returns the identity value for the monoid type.
9596
96-
This method must be overridden in subclasses of Monoid.
97+
This method must be overridden in subclasses of Monoid
9798
9899
"""
99100
raise NotImplementedError
100101

101102

102103
# 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+
104107
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")
105122
self.value = None
106123

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)
108127
return other
109128

110129
def __radd__(self, other: Self):
130+
if not isinstance(other, Monoid):
131+
return self.superclass(other)
111132
return other
112133

113134
def __repr__(self):
@@ -117,11 +138,11 @@ def __repr__(self):
117138
IDENTITY = _MonoidIdentity()
118139

119140

120-
# allows: mconcat([Monoida, Monoidb]) #Bad
141+
# mconcat([Monoida, Monoidb]) not throws an error :nice
121142
def mconcat[a: Monoid](monoid_list: Iterable[a]) -> a:
122143
"""Takes a list of monoid values and reduces them to a single value
123144
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
125146
"""
126147
it = monoid_list.__iter__()
127148

0 commit comments

Comments
 (0)
Please sign in to comment.