///|
pub(open) trait Semigroup {
op_add(Self, Self) -> Self
concat(Self, Self) -> Self = _
concat_option(Self, Self?) -> Self = _
concat_to_option(Self?, Self) -> Self? = _
concat_many(Self, Many[Self]) -> Self = _
concat_array(Self, Array[Self]) -> Self = _
concat_iter(Self, Iter[Self]) -> Self = _
}
///|
impl Semigroup with concat(a, b) {
a.op_add(b)
}
///|
impl Semigroup with concat_option(a, b) {
match b {
Some(b) => a.op_add(b)
None => a
}
}
///|
impl Semigroup with concat_to_option(a, b) {
match a {
Some(a) => Some(a.op_add(b))
None => Some(b)
}
}
///|
impl Semigroup with concat_many(x, xs) {
xs.fold(init=x, Semigroup::concat)
}
///|
impl Semigroup with concat_array(x, xs) {
xs.fold(init=x, Semigroup::concat)
}
///|
impl Semigroup with concat_iter(x, xs) {
xs.fold(init=x, Semigroup::concat)
}
///|
pub impl Semigroup for Unit with op_add(_x, _y) {
()
}
///|
pub impl Semigroup for Int with op_add(_x, _y) {
_x + _y
} ///|
///|
pub impl Semigroup for UInt with op_add(_x, _y) {
_x + _y
}
///|
pub impl[A] Semigroup for Array[A] with op_add(_x, _y) {
_x + _y
}
///|
pub impl Semigroup for String with op_add(x, y) {
x + y
}
///|
pub impl Semigroup for String with concat_many(x, y) {
Semigroup::concat_iter(x, y.inner().iter())
}
///|
pub impl Semigroup for String with concat_iter(x, y) {
let builder = StringBuilder::new()
builder.write_string(x)
for s in y {
builder.write_string(s)
}
builder.to_string()
}
///|
pub impl[A : Semigroup] Semigroup for A? with op_add(a, b) {
match (a, b) {
(Some(a), Some(b)) => Some(a.op_add(b))
(Some(_) as fa, None) => fa
(None, fb) => fb
}
}
///|
pub fn[A : Semigroup] concat3(a : A, b : A, c : A) -> A {
a.op_add(b).op_add(c)
}
///|
test "concat" {
let a = Semigroup::concat([1], [2])
println(a)
}