Source code for haskpy.types.monoids
"""Simple monoids
.. autosummary::
:toctree:
Sum
All
Any
String
Endo
.. todo::
``Product``
"""
import attr
import hypothesis.strategies as st
from haskpy.typeclasses import Monoid, Commutative, Hashable, Eq
from haskpy.utils import identity
from haskpy.internal import (
class_property,
class_function,
immutable,
)
from haskpy.testing import eq_test
from haskpy import testing
[docs]@immutable
class Sum(Commutative, Monoid, Hashable, Eq):
"""Sum monoid"""
number = attr.ib()
[docs] @class_property
def empty(cls):
return cls(0)
[docs] def append(self, x):
return Sum(self.number + x.number)
[docs] def __eq__(self, other):
return self.number == other.number
def __repr__(self):
return "Sum({})".format(repr(self.number))
@class_function
def sample_value(cls):
return st.integers().map(Sum)
sample_type = testing.sample_type_from_value()
sample_eq_type = sample_type
sample_semigroup_type = sample_type
sample_commutative_type = sample_type
sample_monoid_type = sample_type
sample_hashable_type = sample_type
[docs]@immutable
class All(Commutative, Monoid, Hashable, Eq):
"""All monoid"""
boolean = attr.ib()
[docs] @class_property
def empty(cls):
return cls(True)
[docs] def append(self, x):
return All(self.boolean and x.boolean)
[docs] def __eq__(self, other):
return self.boolean == other.boolean
def __repr__(self):
return "All({})".format(repr(self.boolean))
@class_function
def sample_value(cls):
return st.booleans().map(All)
sample_type = testing.sample_type_from_value()
sample_eq_type = sample_type
sample_semigroup_type = sample_type
sample_commutative_type = sample_type
sample_monoid_type = sample_type
sample_hashable_type = sample_type
[docs]@immutable
class Any(Commutative, Monoid, Hashable, Eq):
"""Any monoid"""
boolean = attr.ib()
[docs] @class_property
def empty(cls):
return cls(False)
[docs] def append(self, x):
return Any(self.boolean or x.boolean)
[docs] def __eq__(self, other):
return self.boolean == other.boolean
def __repr__(self):
return "Any({})".format(repr(self.boolean))
@class_function
def sample_value(cls):
return st.booleans().map(Any)
sample_type = testing.sample_type_from_value()
sample_eq_type = sample_type
sample_semigroup_type = sample_type
sample_commutative_type = sample_type
sample_monoid_type = sample_type
sample_hashable_type = sample_type
[docs]@immutable
class String(Monoid, Hashable, Eq):
"""String monoid"""
string = attr.ib(converter=str)
[docs] @class_property
def empty(cls):
return cls("")
[docs] def append(self, s):
return String(self.string + s.string)
[docs] def __eq__(self, other):
return self.string == other.string
def __str__(self):
return self.string
def __repr__(self):
return "String({})".format(repr(self.string))
@class_function
def sample_value(cls):
return st.text().map(lambda s: String(s))
sample_type = testing.sample_type_from_value()
sample_eq_type = sample_type
sample_semigroup_type = sample_type
sample_monoid_type = sample_type
sample_hashable_type = sample_type
[docs]@immutable
class Endo(Monoid):
"""Endofunction monoid (a -> a)"""
app_endo = attr.ib()
[docs] @class_property
def empty(cls):
return cls(identity)
[docs] def append(self, f):
# Append by composing
return Endo(lambda a: self.app_endo(f.app_endo(a)))
def __repr__(self):
return "Endo({})".format(self.app_endo)
[docs] def __eq_test__(self, other, data, input_strategy=st.integers()):
x = data.draw(input_strategy)
return eq_test(self.app_endo(x), other.app_endo(x), data)
@class_function
def sample_value(cls, a):
return testing.sample_function(a).map(lambda f: Endo(f))
sample_type = testing.sample_type_from_value(
testing.sample_eq_type(),
)
sample_semigroup_type = sample_type
sample_monoid_type = sample_type