メモ代わりに昨日今日で勉強したり実装したことをざっくりと書いておく。
まずJSONにおけるあらゆるの存在する領域をunivとする。univの定義はCatyのスキーマで書けばこう。(実際には実装上の都合というか効率化の観点から、univは処理系が天下り的に与えている。)
type univ = string | number | boolean | null | array | object;
一方でunivがまずあって、そこから文字列や整数だけを取り出す事を考えてみる。Catyスキーマにはスキーマ属性として一部の述語が書けるようになっているが、そこにis_numberやis_stringといった物があると考える。この場合、stringやintegerはunivからそういった条件に合致するものを取り出した集合と考えられる。以下はいろいろ端折った例。
type string = univ(is_string=true); type number = univ(is_number=true); : :
通常のCatyスキーマでもスキーマ属性は多用される。例えば0以上の整数だったらtype positive = integer(minimum=0);などと定義する。つまり、トップレベルに存在する型とユーザー定義による部分型は本質的に違わない。
そして上記のように型=述語であり、ある値の領域を狭めて別の領域を作るものである。つまり型定義はデータベースなどの問い合わせ言語になる。以下は適当な例。
type Person = {
"name": string,
"birth": {
"year": integer,
"month": integer,
"day": integer,
},
"hobbies": [string*],
};
例えばこのPersonの定義に対しては、「1984年生まれで音楽が趣味の一つ」という型を定義できる。
type Query = {
"name": string,
"birth": {
"year": integer(minimum=1984),
"month": integer,
"day": integer,
},
"hobbies":{["music", string{0,}]}, // "music"と任意個の文字列を持った集合
},
};
そしてこれはクエリにもなるという話だが、これをどうやって使うかは実装次第。例えば型に対応したデータベースからカーソルを取得するget-db-cursorと、カーソルから値をフィルタリングして取得するfilterというコマンドがあるとすれば、こんな感じになる。
type Cursor<T> = ...; //どうせforeign型なので略。 command get-db-cursor<T> :: void -> Cursor<T>; command filter<S, T> :: Cursor<S> -> [T*]; //Tがクエリに使われる。
get-db-cursor<Person> | filter<Query>
この時のクエリはologで表現するなら以下のようなものになる。

この図がpullbackになっている事に注目。つまりある型へのクエリは、その型の上に構成されるpullbackというわけだな。
この辺もやはりSpivakが書いているそうで、以下はまだ読んでないけど関連する論文。
現在実装している物は上記の例とはまた違っているが、まあエッセンスは一緒。言われてみれば「スキーマ定義をクエリに使えば?」というのは極めてシンプルでイケてる方法なんだが、しかしそれになかなか気が付けないんだよな。
そういや檜山さんからグラフへのクエリとしてSparqlはどうだったんだみたいな話を振られたが、Sparqlは確かにWHERE句はRDFトリプルをプレーンテキストにシリアライズした物だし、CONSTRUCTを使えばRDFグラフが返ってくるのでグラフに対してグラフを使って問い合わせて部分グラフを得るという点じゃ似ていなくもないけど、そもそもRDF自体が前に書いた通りイケてないので、今更ここから得られる物はそんなにない気がする。
ギターという楽器が如何に進歩を止めていたかを如実に表している物の一つに、弦のテンションの問題がある。実は以前からD'Addarioのテンションチャートを参考に自分でバラ弦を組み合わせたカスタムゲージを使っていたが、今後はこのBalanced Tensionだけでいいかもしれない。
ページを見れば分かる通り、多くのギターの弦セットは2弦が緩くて4〜5弦がキツく、6弦がやや緩いというテンションのバランスになっている。このバランスで何が問題になるかというと、まずダウンチューニングした時に2弦、3弦、6弦が緩くて使い物にならなくなる。かといってセットを上げれば残りの弦がキツくなりすぎる。同じ事はまあ普通の弦セットでも起こる事だが、特にダウンチューニングでは6弦のみさらに1音下げるドロップチューニングがあるので、その場合はより問題は深刻になる。一方でBalanced Tensionの場合は相対的にまだマシなレベルには留まっている。
流石に6弦が050以上のセットはラインナップにないが、まあそこはカスタムゲージを使うということで。スタンダードB前後で使うことを考えると、012, 016, 020, 030, 040, 054ぐらいか。バリトンギターなのでこのぐらいで充分だろう。040がバラで売ってなかったら039か042で妥協か。
ジャンクギター・ベースの修理改造は「コレクション」「工作」「演奏」の3つの趣味を全部同時にできるが、時間はかかるしそもそも安上がりかというと絶対に違う。大体まともなギターパーツの相場観としては
とまあ、そこそこの値段だ。当然毎回そんなパーツを買っているわけではないが、電装系は常に必要なので3,000円ぐらい、塗装をやり直す場合はポアーステインと水性ニスという安上がり構成でも2,000円以上なので、大体ジャンク品は1,000円〜2,000円ぐらいで買えることを考えれば、普通に楽器本体よりもコストがかかる。そしてジャンク品はさらに調整の手間がかかる。
というわけでまずそんな奴はいないと思うが、「ジャンク品を買って直せば安上がり」みたいな思考は止めた方がいい。最終的にかかるコストを考えると、最新の安ギターかエントリーモデルを買った方が楽器の性能的にもマシな事が十分考えられる。
といった要素を組み合わせてワンオフモデルを組み上げるのがジャンクギター修理の面白さなので、ぶっちゃけDIY全般に言えるが「安く済ませる」を目的にするとろくな事にならんと思う。
久しぶりに自分の曲を演奏しようかと思ってうろ覚えの部分の確認に楽譜というかタブ譜を見てビックリ。2曲ほど間違ってたというか、実際の演奏と食い違ってた。ミスがあったのは以下の2曲。
なんで自分の曲の楽譜でそんなミスをするかというとだな、録音中にもっといいフレーズが思い浮かんだのでそれを採用して、そんで楽譜を直し忘れるというのがその理由。
えー、中断したりなんだりで紆余曲折あったジャンクギターのリペアですが、まあ書いてある通りちょっと無理があったので中止ということで。いや流石にマズそうだったんでねえ。
でも実はまだジャンク品は手元にいくつかあって、修理にかかっていたりする。
なんでもページの内容にFC2から著作権がどうとかのイチャモンが付けられたそうで、twitterでコピーを公開してくれる人を募集していた。内容的に引用の範疇だと思うのでFC2の主張はどうなんだと思いつつも、これだけのアーカイブがなくなるのは問題だなあと思うのでとりあえずこっちで公開。あんまサーバが強力じゃないんで、アクセスが増えるとヤバいかも知れんが。あとリンク先まで全部ミラーしているわけではないが、それはまあちょこちょこ進める。
移転先が見つかったら、こっちのページからはリダイレクトをすればまあ大丈夫か。
またbitbucketで問題に出くわしたというかバグを発見したが、先人がいた模様。
バカなんじゃないかと思った。いや、煽り抜きでこれは流石にダメ過ぎるだろ。一応末尾の/followを削ればアクセスできるのだが、問題はそこじゃない事は既に書かれている。なんつーか、bitbucketみたいなサービスでもこんな仕様にしちゃうんだというか。そして未だに解決していないというね。
Ozzfest2日目に行ってきた。俺と妹が行ったときには物販でOzzfest Tシャツが売りきれていたので、Black SabbathのTシャツとバンダナを購入。海外のLサイズを買ってしまったのでかなりブカブカだが、まあいいや。女性用のサイズを買った妹はピッタリだったが、ここでの問題は妹も同じTシャツをチョイスしたというところだ。誰に似たんだ、誰に。
でまあさすがに疲れているので、以下Black Sabbath以外は軽めに。飯とか休憩のためにろくに見てなかったアーティストは省略。
そしてBlack Sabbathである。あらゆるヘヴィミュージックの母体、怪物達のエキドゥナ、大始祖、初めにSabbathありきである。90分のセットリストとなると、海外でのライヴのセットリストからしても予想は付いてはいたが、いやでもいきなりWar Pigsはヤバいだろう。もうこの時点で全員前線に突撃、密度の増加っぷりが半端ないことに。特にOzzyからはマイクを振られなかったけど(まあ日本人メインだから気を遣ったんだろうね)、でも結構なシンガロングが発生していたのでみんな予習はしてきたっぽい。
そしてWar Pigsに続いてInto the Voidというまさにベスト選曲の流れにもうテンションが上がりっぱなし。当然俺はここでもシンガロングというか、いや俺この曲歌詞覚えてるとかそういうレベルじゃなくてリフもソロも通しで練習したことあるんで、曲の構成とか完璧に把握済みなんですよ。というか今日のセットリストの大半は弾いたことがあるし、録音した事のある奴も結構あったりする。
3rdアルバムの締めであるInto the Voidに続くのはそれと対をなす4thアルバムの締めであるUnder the Sun。ヘヴィなリフからスピードパートに雪崩れ込んでまたヘヴィなミッドテンポという構成は同じながら、ほぼワンコードで押し通す前者に対してより多彩な展開を聴かせる後者がアルバムとしての質の違いを体現しているなどという事を考えて聴いているはずもなく、ここでも延々叫んで拳を振り上げていたのは言うまでもない。
こうして書いていくとキリがないので以下にセットリストを載せるけど、もうこれ見た瞬間に初期Black Sabbathのファンは瞬殺ですよ。
もう見たまんま、初期作からのベスト選曲。110〜120分のセットだったらこれにThe Wizard, Electric Funeral, Sweet Leaf, Tommorow's Dreamなどといった曲を入れればそれで成立しちゃうってぐらい。いや5th以降にも良い曲は入っているし、Sabbath Bloody SabbathもSymptom of Universeもフルで聴きたいっちゃそうだけど、原点回帰アルバムとされる「13」が控えていてそこからもチョイスするとなると、全体の雰囲気を考えても最初の4枚から殆どを選ぶことになるよな。
というわけで、もう90分間歌いっぱなし叫びっぱなし。実際にBlack Sabbathを体験して改めて確信したが、Ozzyは客の煽り方が上手いというか、ぶっちゃけOzzyに合わせて手拍子して、叫んで、拳を振り上げるというのが滅茶苦茶楽しいんだよね。よくよく見ればどう考えてもリズムが狂ってるシーンとかあったと思うんだけど、「Ozzyがやってるし演奏陣も特に突っ込んでねえな」という事で何も問題なかったりする。
あと生で見るとやっぱBlack Sabbathの演奏陣はやっぱ異常で、Tony Ioomiは中指と薬指の先端が義指というのが実際に目で見ても信じられないぐらい熱いプレイを聴かせるし、Geezer Butlerのベースプレイに至っては生で見ても何やってんのかさっぱりわからん事がある。あれ高速ワンフィンガーとか使ってんのか? Bill Wardがいなかったのが心残りではあるが、ぶっちゃけ健康面でも相当衰えていたみたいだし、無理して死なれても困るので、まあそこは。代役はOzzyのソロバンドでもプレイしてるTommy Clufetosで、フィルインとかに特に顕著な違いはあるんだけど、ちょっと違うかもと思ったのはBlack Sabbathの静寂パートぐらい。ドラムソロもなかなか盛り上がったというか、ソロの終わりからIron Manに雪崩れ込む演出はかなり格好良かった。
あと「13」からの先行公開曲のGod Is Dead?が全く違和感なく混ざっていたのも素晴らしく、これならもう「13」は現代的にアップデートされた初期Sabbathというのを期待しても問題なかろう。
最後は3rdアルバム屈指の名曲というか3連ヘヴィリフのお手本みたいなChildren of the Graveで一旦締めて、アンコールでSabbath Bloody Sabbathのイントロで溜めてからのParanoidで大団円。いやー、自分の生まれる前に結成どころか一旦空中分解したOzzy在籍時のBlack Sabbathを観られて本当に良かった。
Ozzfestの動画が早速Youtubeにバンバン上がっていて、いやー取り締まりにも限界があるなーとか、そういや入場時のボディチェックとかザルだったなあとか、まあそういう事を思いつつ、一方でメタルが南米から東南アジア、中東までそのシーンを広げた背景にはそういった動画投稿サイト及びソーシャルメディアでの口コミも大きな要因なんだよなあとも思う。実際2010年にはイスラエルでOzzfestが開催されたしね。
ヘヴィメタルって他のどのロック系のジャンルよりも演奏重視だから、そういう意味じゃ言葉の壁を乗り越えやすい面があると思う。そもそも延々グロウルやスクリームしてるからネイティヴでも全然聴き取れないケースもあるという身も蓋もない側面があるのはそうだが、何にせよ他の共感重視でハイコンテキストな音楽に比べると、世界を相手にしたソーシャルメディアでの露出じゃ有利かもしれない。
で、それぞれの国内ローカルに限った話にしても、面倒な事抜きに動画一本で凄さが分かるローコンテキストっぷりってやっぱりアドヴァンテージではあって、昨日凄まじいライヴを披露した人間椅子って、Youtubeで彼らの音楽に触れた20代のファンが増えているらしい。ってか俺もYoutubeで見てその演奏と楽曲のレヴェルの高さに度肝を抜かされたクチだ。そういやSteel PantherもYoutubeも交えた口コミベースで人気を博してメジャーデビューしたんだっけか。
などという事情を鑑みるに、Anthemに加えてSteel Pantherも人間椅子も扱わないロキノン系のWeb媒体はゴミクズ以下の産廃だなあと思うことしきり。元々アンチメタルだとは聞いていたが、まさか一言も触れないとは恐れ入った。そしてOzzfestのものではないとはいえ人間椅子のライヴ動画が徳間ジャパンからYoutubeに3本ほどあげられ、マジでロキノンみたいな媒体は不要だなあと思うことしきり。まあ、メタル系もBurrn!とか大概だと思うが。
ちなみにいずれもOzzfestでも披露された曲。これをレポートしないのはマジでメディアとしてどうよ。
あと針の山は替え歌カヴァーなんだけど、原曲はこちら。
追記: 人面瘡と深淵の動画も上がってた。これら5曲がOzzfestのセットリストだったので、マーケティング的にも正解ですよ。
たしか曲順は
だったはず。
恐ろしい結果が見られるのだが、これ一体どういう事なんだ。水からの伝言みたいな明らかに「俄には信じ難い」という反応になりそうなものを8割近くの学生が否定できてないとか末法にも程がある。いや本当に一体どういう教育をしたらこうなるんだろうと思ったら、なんと理科の授業でも擬似科学を肯定的に扱っていたり……これってやっぱ教師が大バカなのか?
なんつーか、この手の基礎的なリテラシーの教育に失敗すると後々の社会的コストがシャレにならんと思うのだが、一方で教育技術について研究しているTOSSがEM菌、ゲーム脳などと同様に水からの伝言を取り上げていたこともあるので、その辺からの調査も行った方がいいのかなと思う。
この件についてはTwitterにもちょろっと書いたけど、こっちで大雑把にまとめておく。
まず話の前提として生保受給者への風当たりの強さについてだが、仮に100人の生保受給者全員がもらった金をパチンコなどの博打に費やしたり酒飲んで終わりだったとしても、生保を止めたところで「酒と博打で生保でもらった金を溶かしちゃう100人のろくでなし」が「酒と博打のために悪事を働く100人の強盗」になりかねない(そうでなきゃホームレス)。だから社会保証ってのは弱者の保護であると同時に治安維持の側面もあるわけで、実にろくでもない受給者を想像した上でなおそれでも福祉の網にかけないといけない。
そもそも生保受けるような状況で博打にハマってるようなのはギャンブル中毒をはじめ精神面の問題である可能性があるので、普通に考えりゃ必要なのは治療と教育だ。そんでこれはある意味で生保とは直行しているので、結局ある一定のラインを越えて困窮していたら問答無用で生保の網にかけて、その上で先に挙げたような個人でどうにかできない(中毒状態は個人の努力じゃどうにもならん)問題は行政の方でどうにかするという、そういう流れになる。
で、そういう問題を抱えているか否かに関わらず、相互扶助の強化なんぞやったら生保を巡るトラブルが山のように出るだろう。金がないと人間がどれだけクソになるかなんてのは俺だって見てきたというか、俺の死んだオヤジは生前にどれほどの悪事をしでかしたか数えるのも嫌なクソ野郎だったが、そのクソさ加減は概ね収入に反比例していたし、一番クソでなかった時期のオヤジですら養えるかと言われると明確にNoだ。そして福祉というのはそうやって見知った間柄だからこそ起こる問題を、税金として徴収して匿名化した金でシステムとして解決するという事でもある。実際問題、穀潰しの親族を養うのは嫌でも、穀潰しに苦しめられている人を助けるのはやぶさかでもないって感情は割と自然なんじゃねえの?
そして何より今はインタゲの方向で金融政策を舵取りすることになったんだから、むしろ社会保障費は増やさないといけない。特に生活保護は大半が消費に回るのだから、生活保護の受給者を通じてその生活圏内へと所得の再分配を行っているのに等しく、金融緩和で溢れたマネーを循環させて景気を回復させる方法としてはかなり直接的かつ効果が高いと思われる。当然、景気の回復に従って社会全体では雇用も回復するだろうから、結果として社会保証費の負担は軽くなるだろう。それに対して社会保証費の切り下げで「物価下落を見越して」なんて言ったらインタゲへの疑問符を市場に発信することになるので、金融政策と矛盾してしまう。
だからあらゆる観点から見て相互扶助の強化と生活保護引き下げは現状ではウンコとしかいいようがない。
「生保受給者は頑張ってるけど困窮してる人達だから保護せねば」と考えるのも「ろくでなしだから保護する必要なし」と考えるのも間違っていて、「個人ではどうしたって許容できない事があるんだから、社会システムを可能な限り寛容に設計すべし」という話。だから「努力している哀れな弱者」とか「ろくでなしの食い詰め者」といった属性が生保の判断基準になってはダメで、じゃあどこで判断するかというとそらもう金しかないでしょと。
そこから抜け出すための方策はまた別の問題。景気の回復で勝手にどうにかなる部分も多いと思われる。何にせよ再分配強化に熱心な政党ほど今のような金融政策を提唱して景気の回復に努めるべきだったんだが、時間は戻らんからなあ。それに民主党の反省会の記事をちょこちょこ見る限りでは、未だに何がダメだったのか理解してなさげだし。
あと俺が都会に出て知的労働に就けている理由の大半は教育なので、生保受給者の子供が高等教育を受けられないというのはかなりマズい。高等教育を受けられないという事は人生の選択肢がそれだけ狭まる事なので、貧困の再生産に容易につながる。だから本来は大学も国立は無償化されて然るべきなのだが。
来年のOzzfest Japanについても肯定的な発言だねえ。でもプロモーターは変えた方がいいと思う。今回のラインナップって邦ロックファンと洋ロックファンとヘヴィメタルファンが全然被ってないという事実に気付かず、それで結局ももクロで初日のチケット捌いたって感じだもの。
2日目はToolとBlack Sabbathとなればコアなリスナーは押しかけるとしても、初日は「Slipknotぐらいしか食指が動かんし、他のフェスでも観られるし」ってなった人はメタルファンには多かったんじゃないのかね。いろんなバンドに触れるのもフェスの楽しみとはいうけど、それは自分の目当てが充実していればこそでしょ。あとそういう懐の広さを持ったリスナーを育てる方向で音楽ジャーナリズムが活動してきたかというと、絶対に違うだろう。
今回はOzzyのいるBlack Sabbathの初来日+第1回Ozzfest Japanというご祝儀での集客という面もあったと思うので、次回も似たようなノリでラインナップ決めたら成功するかはわからんぞ。
またオーディオマニア(=オカルトマニア)以外誰も喜ばないような商品の宣伝かよと思ったら、「ブラインドテストではまったく分からなかっただろう」と正直に書いてあった。結論の「従来の工程で生産されるCDの品質に大きな問題があったわけでもない。たまたま欲しかったアルバムがBlu-spec CD2として店頭に並んでいたら、通常の国内盤と同じ感覚で購入されることをおすすめしたい。 」というのも、まあ妥当な所だと思われる。
今の時代はどうせみんなCDを買ってもリッピングしてPCに保存してんだから、訂正不能な読み取りエラーが発生するようなものでない限り、CDの素材なんてなんだっていいんだよな。CDプレイヤーで再生する場合は訂正可能なエラーの発生率で違いがあるという線はあるというか、SHM-CDの方が訂正可能なエラーが増大していたなんてレポートがあった。もっともそれが良いといえるかどうかは記事にある通り別問題。
またしても適当なCatyのメモ書き。
ここ最近Catyスキーマに入った強力な機能は、タグに型定義が書けるようになり、また文字列や数値の排他条件が書けるようになったこと。具体例で示す。
type NonFoo = @(string(excludes=["Foo"])) univ;
ここでNonFooはFooでない型という意味になる。なので以下のような型定義が書けるようになる。
type A = @Foo univ | NonFoo; //二つの型は排他。あまり意味がない例だが
type B<T> = (NonFoo & T) | @Foo {"data": T}; //任意のFooタグの付いていないでないデータ型について、そのデータ型そのものかFooで修飾されたものかの識別
type C = (@(string(excludes=["Bar"])) univ) & NonFoo; //タグがFooでもBarでもない型
string型やnumber型のexcludesは単独でも使える。例えばこんなの
type nonZero = integer(excludes=[0]); //0でない
これがなんの約に立つかというと、例えばMaybeを定義するのに使える。
とりあえずCatyのデータ全体をUと置くとして、Maybe同様のデータ型を作ると言うことは、データ全体に⊥(ボトム)を追加するのと同じ。U∪⊥というデータはCatyスキーマではuniv|⊥となりそうだが、そもそもunivがforeignを含めたあらゆるデータの事なので、そこに何も付け加える事はできない。
じゃあどうするかというと、excludes属性を使ってしまう。つまり予めタグ名を予約してしまい、それはユーザーが使えないようにする。例えばMaybeの場合、こういう風に定義できる。(型のみ。)
type Maybe<T> = Just<T> | Nothing; type Just<T> = @(string(excludes=["__nothing"])) T; type Nothing = @__nothing undefined;
当たり前だがいずれもCatyのデータ型の中に存在するので、こうした規約が前提ではあるが普通にwhenやcaseで扱えるようになる。
excludes属性の導入で可能になったことの一つに、環境への更新モナドが作れるようになった事がある。
環境への更新データをM, 通常のデータをA, Bとすると、例えば環境への更新リクエストを行うコマンドfの出力型はA -> [B, M]みたいになる。実際にはタグを使って
command f :: A -> Mut<B>; type Mut<T> = (T & @(string(excludes=["__mutate"])) univ) | @__mutating [B, M]
のようにする。
この時にそのままでは入力がBで出力がCのコマンドg :: B -> Cなどはfに結合できないが、これをg' :: Mut<B> -> Mut<C>に拡張する操作を導入すれば、f | m{g}が書けるようになる。この時gの内部には一切触れず、gにはMut<B>のB成分だけを渡してMの部分は素通しで良い。当然mは関手なので、f | m{g} | m{h}...とf | m{g | h}...は等しい必要がある。
この時にm内部のコマンドからmへの入力のM成分へのアクセス手段を与えておけば、mは両モナドになる。実例を挙げると、RDBMSのREAD COMMITTEDなトランザクションとかその辺。
適当に書き散らかしたが、ここ最近実装したり勉強していたのはこの辺りの話。更新リクエストのコミットとか、例外処理との絡みはまあ実装できたら。
まだ実装すると決まっているわけではないんだが、Catyでちゃんとモナドを書けるようにするにはどうすればいいかというのは考えていなくもない。とりあえずわかりやすいところだと、Listモナドについて考えてみる。
signature Monad = {
/** 関手の対象部分 */
type Object<T>;
/** 関手の射部分(入力の第二要素は文字列化したCatyScript) */
command map<S, T> :: [Object<S>, string] -> Object<T>;
/** 単位 */
command unit<T> :: T -> Object<T>;
/** 乗法 */
command mult<T> :: Object<Object<T>> -> Object<T>;
};
class List conforms Monad = {
type Object<T> = [T*];
command map<S, T> :: [Object<S>, string] -> Object<T> = {
[$.0 > input, $.1 > src];
%input | each {
[pass, %src] | eval
}
};
command unit<T> :: T -> Object<T> = {[pass]};
command mult<T> :: Object<Object<T>> -> Object<T> = {list:concat};
};
現状では指数型がないので、文字列をevalという超ダサいことになっている。指数型を入れるのは檜山さんが乗り気ではなく、俺もちょっとやり過ぎな気がしなくもない。じゃあどうするかというとマクロという手があるが、これがまた大変。Catyスキーマとスクリプトのレベルでまともなマクロを書こうとすると、Lispのようにソースコードとデータが同一という分けではないという問題が発生する。レイフィケーションでどうにかできる可能性がなくもないが、いやそれにしたって厳しい。Listモナドはぶっちゃけ組み込みのeachを呼ぶだけなので問題ないが、Maybeあたりはどうだろう。何か適当にマクロ展開っぽいコードを考えると、
class Maybe conforms Monad = {
type Object<T> = @__just T | @__nothing univ;
macro map<S, T> :: Object<S> -> Object<T> = maybe {
$just$,
} => when {__just => @__just $just$, __nothing ==> pass};
command unit<T> :: T -> Object<T> = {@__just pass};
command mult<T> :: Object<Object<T>> -> Object<T> = {untagged};
};
$<NAME>$の部分は任意のCatyScriptのコードブロックが挿入され、それが後段で展開されるという寸法。デバッグの事を考えると、元がマクロだったという情報はどうにかして残しておかないとマズそうだが。使い方としてはこうなると思う。
some_command | maybe {some_command2 | some_command3} | when {
__just => pass,
__nothing=> some_command4
}
このマクロ展開方式の問題は再帰的な処理がそのままでは書けないことで、またあくまでもマクロなので、どこでどう使われるかわかったものではないというのも頭が痛い。
実際にはマクロ展開をしないで$...$の中身と展開しきる前の中間の構文木($...$だけを展開していない状態)を別個に持っておき、いざ処理が$...$に差し掛かったら処理をディスパッチという方法でこの問題は解決できるっちゃできるのだが。
というわけでモナド関連はペンディング。出来なくもないけどいろいろアレなので別の問題を優先というところ。