しりとりの圏 -- JavaScriptによる実装
/* HSCat.js -- Hiragana Shiritori Category *//*
* 一般的な文字列処理関数
*/// 文字列の連接
function concat(s, t) { // s, t は文字列と仮定
return String.prototype.concat.call(s, t);
}// 文字列の最初の文字(ただし文字番号が返る)
function first(s) { // s は文字列と仮定
return s.charCodeAt(0);
}// 文字列の最後の文字(ただし文字番号が返る)
function last(s) { // s は文字列と仮定
return s.charCodeAt(s.length - 1);
}// 文字列の最初の文字を除いたもの
function butfirst(s){ // s は文字列と仮定
return s.substring(1);
}// 特定の1文字からなる文字列(引数は文字番号)
function unit(c) { // c は整数と仮定
return String.fromCharCode(c);
}// ひらがな文字かどうかを判定(引数は文字番号)
function isHiraganaCharCode(c) { // c は整数と仮定
return (
(0x3041 <= c && c <= 0x308F) // 'ぁ' から 'わ'
||
c === 0x3092 // 'を'
||
c === 0x3093 // 'ん'
||
c === 0x30FC // 'ー'
);
}// 非空(Non Empty)なひらがな文字列かどうかを判定
function isHiraganaNEString(s) { // s は文字列と仮定
if (s.length === 0) return false;
for (var i = 0; i < s.length; i++) {
if (!isHiraganaCharCode(s.charCodeAt(i))) return false;
}
return true;
}// しりとり方式の文字列連接 (sconc = Shiritori CONCat)
function sconc(s, t) { // s, t は文字列と仮定
return concat(s, butfirst(t));
}/*
* 対話的に使うための便利関数
*/// 文字の番号を返す
function ord(c) {
return c.charCodeAt(0);
}// 番号に対応する文字を返す
function chr(n) {
return String.fromCharCode(n);
}/* ================================================== */
/*
* ひらがなのしりとり圏(HSCat)の実装
*/// 名前空間を提供するオブジェクト
var HSCat = {
};// この圏の対象かどうかを判定
HSCat.isObject = function(x) {
return (
(typeof x === 'number')
&&
isHiraganaCharCode(x)
);
};// この圏の射かどうかを判定
HSCat.isMorphism = function(x) {
return (
(typeof x === 'string' || x instanceof String)
&&
isHiraganaNEString(x)
);
};// 射の域
HSCat.dom = function(s) {
if (!HSCat.isMorphism(s)) throw "not a morphism";
return first(s);
};// 射の余域
HSCat. cod = function(s) {
if (!HSCat.isMorphism(s)) throw "not a morphism";
return last(s);
};// sとtが結合可能かどうかを判定
HSCat.composable = function(s, t) {
return (
HSCat.isMorphism(s)
&&
HSCat.isMorphism(t)
&&
HSCat.cod(s) === HSCat.dom(t) // 結合可能性の条件
);
};// sとtを結合(合成)
HSCat.compose = function(s, t) {
if (!HSCat.composable(s, t)) throw "canot compose";
return sconc(s, t);
};// 恒等
HSCat.id = function(a) {
if (!HSCat.isObject(a)) throw "not an object";
return unit(a);
};