I want to do the following in a generic way:
type
Constant[T] = object
value: T
# For testing: 'int' acts as monoid under addition
proc `&`(a: int, b: int): int =
a + b
proc `$`[T](a: Constant[T]): string =
$a.value
proc `==`[T](a: Constant[T], b: Constant[T]): bool =
a.value == b.value
proc `&`[T](a: Constant[T], b: Constant[T]): Constant[T] =
Constant[T](value: a.value & b.value)
proc identity[T](a: Constant[T]): Constant[T] =
Constant[T](value: 0) # For testing: forced as identity for 'int' under
addition
let ca = Constant[int](value: 3)
let cb = Constant[int](value: 6)
let cc = Constant[int](value: 6)
echo("Compare setoid: ", cb == cc)
echo("Identity monoid: ", identity(ca))
echo("Appended semigroup (=9): ", ca & cb)
I tried the following:
type
Setoid[T] = concept a, b
a.value is T
a == b is bool
Semigroup[T] = concept a, b
a.value is T
a & b is Semigroup[T]
Monoid[T] = concept a of Semigroup[T]
identity(a) is Monoid[T]
Constant[T] = object
value: T
# For testing: 'int' acts as monoid under addition
proc `&`(a: int, b: int): int =
a + b
proc `$`[T](a: Constant[T]): string =
$a.value
proc `==`(a: Setoid, b: Setoid): bool =
echo "Compared" # For testing
a.value == b.value
proc `&`[T](a: Semigroup[T], b: Semigroup[T]): Semigroup[T] =
Semigroup[T](value: a.value & b.value)
proc identity[T](a: Monoid[T]): Monoid[T] =
Monoid[T](value: 0) # For testing: forced as identity for 'int' under
addition
let ca = Constant[int](value: 3)
let cb = Constant[int](value: 6)
let cc = Constant[int](value: 6)
echo("Compare setoid: ", cb == cc)
echo("Identity monoid: ", identity(ca))
echo("Appended semigroup (=9): ", ca & cb)
But can only get the "Compare setoid" to work :( . I am sure I am doing
something stupid. But what?