このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

しりとりの圏 -- 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);
};