文字列は文字列の連結という2項演算に関して semigroup ですよ.あー,いや, monoid か……なんていちいち考えるっぽ?

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2645.pdf
いや,こういう最も原初的で代数的な concept から組み立てあげる方向性は,まったく間違ってはいないし, STL (によらず汎用プログラミング全般) 的にいって王道的進化だとは思うし,非常に個人的な立場から言えば大歓迎なんだけれど.なんていうか……底知れぬ危惧ががが.
http://d.hatena.ne.jp/Cryolite/20070307#c1173362210
#っていうか,上のリンク先のコメントを書いたときの私は,どうやら "accumulate というアルゴリズム" という言葉を, x_1 \oplus x_2 \oplus \dots を計算するアルゴリズム,という意味で使っていたようで,それで「(この意味での) "accumulate というアルゴリズム" が well-defined であるためには semigroup じゃないといけない」という趣旨で,「accumulate というアルゴリズムにおける,値型に対するもっとも緩く汎用な制約は半群 semigroup であること」と口走っていたようです.んぐゎ, C++ の標準ライブラリにおいて定義されている std::accumulate は交換則要りません. std::accumulate の定義は「左から順番に演算した結果 ((x_1 \oplus x_2) \oplus \dots) を返す」なので.このコメント書いたときの私は一体何を考えていたのでしょうか?ただ, std::accumulate 使う人はやはり semigroup という概念を知っていたほうが良い.つまり semigroup であるという情報が分かっていれば, std::accumulate の計算において,てけとーな場所から演算していっても構わなくなるので,実装がこれを活かしてより最適な特殊化を提供する可能性が考えられる.従って, semigroup という概念を把握していないと (特殊化を活かせないという意味で) 損する可能性がある.semigroup であることを活かした特殊化の例としては,上の PDF では (単位元を取れるという要請も付けて) unrolling を引き合いに出していますが,他にも自動並列化ができる,などといった具合.
#あと,自分のコメントの「2項関数の適用順序が固定されるならば左 (右) 半群」は,もう正直書いた本人も意図が分からない.多分, accumulate 使って文字列の列をつなげ,ファイルパスを作るようなことを想定していたような気がするような! (後付け設定)