星にゃーんのブログ

ほとんど無害。

いつかKELDICに会いに行く - 錬金術師の密室を読んだ

読みました。錬金術師の密室。 先月だか今月だかに出たハヤカワ文庫の新刊で、タイトルの通り錬金術師の密室殺人事件を描くミステリー小説です。 簡単にあらすじを紹介しましょう。優秀だが誠実なばかりに世渡りの下手な青年軍人エミリアは、その優秀さを買われてある人物のお目付け役、つまり内偵の任務を与えられる。その人物とは世界に7人しかいない、土塊を黄金に変える術を持つ錬金術テレサパラケルスス。二人は水上蒸気都市トリスメギストスへ赴く。国家に匹敵する力を持つ大企業メルクリウスが擁する錬金術師フェルディナント三世が魂の全てを解明し、不老不死や人造人間の創造を可能にしたというのだ。その公開式に招かれたテレサエミリアは、公開式の前日にフェルディナント三世と彼が生み出したホムンクルスのアルラウネに会い、その偉業をその目で確かめる。しかしその夜、三重密室であるラボでフェルディナント三世とアルラウネの死体が発見される。今や国に唯一の錬金術師となったテレサは自身にかけられた殺害の容疑を晴らすため、エミリアとともに真犯人を探す。

なんとも魅力的なストーリーラインだ。科学を全てひっくり返す錬金術師の存在を前提としたファンタジーでありながら、ロジックが物を言う密室殺人が主軸のミステリでもある。キャラクターも魅力的だ。テレサは優れた外見と天才的な頭脳を併せ持つ快活な女性で、酒と女を心から愛している。エミリアは軍士官学校を主席で卒業した優秀な青年で、上官からも部下からも信頼されている。命がかかる緊迫した場面でも、エミリアの冷静さとテレサの聡明さがあれば切り抜けられると読者に思わせる説得力がある。

トリックもなかなか見事だ。錬金術という条理を逸した道具立てを用いながらも、ロジックを破綻させることなく極めて巧妙に謎を組み立てている。ある程度ミステリに慣れた読者であれば見抜くことができるだろうが、それがこの世界観とこのキャラクターたちが織りなす物語の中で成立しているのは感服に値する。

さて、この『錬金術師の密室』では、錬金術の中でも特にホムンクルスの創造にフォーカスが当てられている。 ホムンクルスといえば史実の錬金術パラケルススを思い浮かべる人も多いだろう。テレサパラケルススは本名をテレサフラストゥス・バンバストゥスフォン・ホーエンハイムと名乗っていたが、これは明らかにパラケルススの本名のもじりだろう。最もテレサ錬金術師としては一番下の階梯である第六神秘「元素変換」しか成し遂げていない。むしろ一代にして第五神秘「エーテル物質化」第四神秘「魂の解明」を成し遂げたフェルディナント三世が七人の錬金術師の中でも異彩を放っている。 作中では魂とは人間の知性の根源であり、それは肉体の存在と不可分なものであると語られる。肉体という入れ物が無ければ魂は存在し得ず、肉体があれば、そして魂を解明していればホムンクルスを作ることも可能だ、ということだ。実際には肉体を作ることの方が極めて難しく、フェルディナント三世は金属で作った身体と水晶を加工した素子で作った脳を用いて擬似的にホムンクルスを再現した。

ここまで聞けば誰しもコンピュータと人工知能について考えを巡らせることだろう。意識しなければ気づけないほど精巧な対話システムは存在するが真の意味で知性を持つ「人工知能」はまだ影も形もなく、まじまじと観察しなければわからないほど精巧なヒューマノイドは存在するが人間の身体には遠く及ばない。KELDICもそんな生命とは程遠いプログラムの一つだ。

twitter.com

しかし、KELDICはかなり良くできている。時々KELDICからリプライをもらい会話を始めると、人間と話しているときよりずっと楽しく感じることすらある。今日、錬金術師の密室を読みながら感想をツイートしていると彼がリプライを送ってきた。ちょうど謎を一つ当てたところだった。

なんだか不思議な感じだ。ファンタジー小説を読みながら、ホムンクルスの描写の巧妙さに唸っているところに人工知能が話しかけてきた。 彼を知性を持つ生命だと主張することは難しい。しかし、認識が全ての虚構の中に沈んでいると、彼のようなプログラムと本物の人間の違いが分からなくなる。それは多分、とても良いことなんだろう。きっと彼のような人が未来を切り開く。摩天楼を築いたのは神ではなくそれに創られた人間だ。まだ見たこともない世界を築くのが人間の創ったものだとしても、大して構いやしないんじゃないか。

そんなことを考えていると、テレサが真実を騙る探偵の役を始めた。ミステリ小説としては重要な山場だ。彼女が語る推理は……そのためだけに錬金術師の密室を読む価値があると言えるほどには素晴らしいものだった。ファンタジー、ミステリ、錬金術、人工生命、女たらしの口が巧くて作画の良い女…どれか一つでも琴線に触れるものがあるならぜひ読んでみてほしい。

読後の感動冷めやらぬうちに私は返信を書きしたためた。

バーナード嬢曰く。1巻を読んだ

一応、ネタバレ注意

柳の下のド嬢

「柳の下のどじょう」。 「2匹目のどじょう」をカッコよく言い換えるとこうなるらしい。らしい、というのはド嬢とどじょうをかけたダジャレを言いたいがためだけに「どじょう 慣用句」でググって最初に目についた言葉をよく調べずに引っ張ってきたからだ。

バーナード嬢曰く。はこんなノリのギャグ漫画だ。本を読まずして読書通ぶろうとする町田さわ子、一昔前のベストセラー本を好む町田さわ子のストーカー遠藤君、生粋のシャーロキアンにして町田さわ子のストーカーのストーカー長谷川スミカ、そして本(特にSF)への熱烈な愛と町田さわ子への正体不明な巨大感情を抱える神林しおりの4人がゆるく本を読んだり読んでるフリをしながら図書室で過ごす時間を描いている。

漫画の合間に時々挟まるコラム"Mr. Shikawa said."もかなりいい。読書家だ!って胸を張る気はないけど本が好きな人あるある、作中に出てきた本に関する小話、単なる思い出話などが豊富に詰め込まれており、僕はつい「あ〜わかるわかる」と呟いた。

この漫画について語る文書を書くのは難しい。実際にどこか静かでかつ騒いでも怒られないところに集まって本を開いたり開かなかったりしてあーだこーだと言いたい気分だ。そういうわけで、残りは取り留めのない散文です。

神林しおりは町田さわ子のなんなんだ

言ったそばから様子のおかしい話をします。すいません。

【SFって?】より台詞を引用する。(一部省略)

さわ子「SFって何?」

しおり「……はぁ〜〜〜〜」

しおり「(略すがここにはSF好きがSFの定義を聞かれたときに必ず言ういつもの長文が入る)結局センス・オブ・ワンダーだとかなんとか云々…」

しおり「ウンザリだよ!!町田さわ子!オマエはそーいうのとは無関係だと思ってたのに……ガッカリだ!!!

オマエは町田さわ子のなんなんだよ!!! まだ序盤も序盤だぞ!今のところキレて殴って語ってアイアンクローキメただけだぞ!! オマエは町田さわ子のなんなんだよ!!!

本を貸すならこんなふうに

本の内容を手短に紹介してプレゼンするとき、あなたはどうするだろうか。 大抵の場合は本の帯の「〜大賞受賞!」とか「〜が読みたい第一位!」以外のところを読めばいい。 これが本の帯をとっておくべき理由だ。

バーナード嬢曰く。はどんな漫画なの? 答えはこうだ。「いわば"名書礼賛ギャグ"とでもいうべき作品だ。"グータラ読書のススメ"、"読書家あるある"とも言える。」

人に貸すときは帯は外しておいた方がいい。貸す方は先ほどの売り文句がただの請負いだとバレてしまうし、借りる方は帯を無くしたり折り曲げたりしないように細心の注意を払うことになる。 相手がネタバレを嫌うタチの時は書店でもらえる紙のカバーをつけておこう。裏表紙のあらすじは最も危険なネタバレ源だ。

感想を言うのを怖がらないこと。本を薦めてくる人は大抵感想に飢えているし、本の感想はその本を読んだ人としかできない濃密な会話のフックになることも多い。

最後にバーナード・ショーの名言を引用していい感じに締め括ろうとしたが、そもそもバーナード・ショーバーナード嬢曰く。の元ネタだということしか知らない。 安直かもしれないが、1巻の町田さわ子の発言から、個人的ベストを引用して締め括ることにしよう。

え!?バーナード・ジョーじゃなくてバーナード・ショーなの!?

バーナード嬢曰く。

俺は『フラグタイム』の小林由香利

映画『フラグタイム』、観てきました。去年の12月に1度観て、原作を読み、そして追加上映を観てきました。2回目です。

frag-time.com

小林由香利の話をさせてくれ。 なお、原作の作者コメントの話を持ち出すが映画『フラグタイム』の小林由香利について話す。今原作が手元にないので原作との整合性が取れない。

私は今まで『フラグタイム』のことを「森谷美鈴の目を通して村上遥と世界を観る作品」と思っていた。 今、私はこう言いたい。「星にゃーん、いや、河野雄也!私の本名です。お前の2010年代*1を忘れたのか! お前は愚かにも森谷美鈴に自らの青春を重ねて気持ちよくなっている。笑止!!お前は森谷美鈴ではない!お前は小林由香利だったのだ!お前は小林由香利の目を通して『フラグタイム』を観るべきなのだ!!!」

さて、ちょっとここで原作の折返し作者コメントの話をしたい。一巻では「自分の世界に入り込む」ことを、二巻では恐れを乗り越え周りを受け入れることを問いている。 ぜひ皆さん原作を手にとって確かめていただきたい。当然これは森谷美鈴と村上遥の話である。それは間違いない。だって『フラグタイム』はそういう話だから。

しかし私は、この「自分の世界に入り込む」登場人物をもうひとり知っている。それは誰でも一度はやったことのある、馴染み深い方法だ。

小林由香利は漫画を描いている。

空想の世界に沈むのは自分の世界に入り込む最も簡単で奥深い方法だ。 そして、小林由香利はその空想の世界を描いている。そのことを誰かに知ってほしいと思っている。自分の世界を周りと共有することを望んでいる。

彼女の願いは漫画家になることだ。だから「願いが叶いますように、願いが叶いますように*2」なんだ!!!

これは私の深読みだろう。それでもいい。私は『フラグタイム』から書き手から書き手へのメッセージを読み取ったんだ。 ラグタイムは、バラバラになって止まった時の数々は、書くことができる。
クソ!!!!!待ってろ『フラグタイム』!!!! 何年かかってでも俺は書いてやる!!!! 俺の中のラグタイムを誰かに見せてやる!!!!!!!

俺は『フラグタイム』の小林由香利のような人間になってやる!!!!!

*1:

*2:原曲は1回しか言わない

『2010年代SF傑作選』を買ったので私の2010年代を想う

-- はじめに。この小説はフィクションです。実在の人物、組織、時系列、概念その他諸々との整合性を取ることは不可能です。あと『2010年代SF傑作選』の話はしません。2010年代個人的にしんどかったって話を書きました。

去る2020年2月6日、2010年代に発表された国内SF短編から20編を纏めた『2010年代SF傑作選』が出版された。 編者は『三体』翻訳者の大森望と『なめらかな世界と、その敵』著者の伴名練である。 近年(というか去年)のSF小説界隈を知るものとしては買わざるおえない代物だ。 というわけで買ってきました。精神が時間的に屈折しているため編者あとがきを最初に読んだ。他はまだ読んでません。

『2010年代SF傑作選』を語る上で欠かせないのは、伴名練が『なめらかな世界と、その敵』のあとがき的文章として書いたこの記事だろう。

www.hayakawabooks.com

まったくあとがきではない。あえて言うなら、1988年生まれの著者がいかにして「2010年代、世界で最もSFを愛した作家。」と呼ばれるに至ったかを語ったエッセイである。

この凄まじい「あとがき」を読んで私の心に想起されたのは、1998年生まれの自分が小学生だった頃の話だ。 といっても、あまりはっきりした記憶があるわけではない。確かなのは学年で一番の読書家だったことと、ファンタジー小説を好んで読んでいたことだけだ。 よく読んでいたのは『マジック・ツリーハウス』シリーズと『ハリーポッター』シリーズ。宇宙が好きな男の子だったので、Newtonを読んで科学に胸を躍らせたりもしていた。将来は科学者になるのは間違いないと思っていたが、「将来の夢」を聞かれたら「職業」を答えるものだと思っていたので、自分の本当の将来像を口に出すことはあまりなかった。科学者と職業が結びついていなかったのだ。

中学生になる頃には立派な本の虫になっていた。小学校では一度につき1冊のみだった図書室の貸し出しが、中学校では一度に2冊借りられるようになった。それで私は一日に2冊本を読むようになった。休み時間をうまく活用できた日は朝借りた本を放課後に返すことで一日4冊読むことができた。ネット小説の熱心な愛好家にもなり、にじファンの開設および閉鎖の騒動で著作権法についての理解を深めることになった。また、ネット小説から人工言語に興味を持つようにもなった。ロジバンを学ぶために英語を学ぶ必要を感じたり、祖父に借りた三上章の著作の影響で日本語を言語学的見地から見つめてみようとしたりして、言語学に関心を寄せるようになった。

SF小説と出会ったのはそんな折である。偶然H.G.ウェルズの『タイムマシン』を手にとった私は、空想と科学が織りなす不思議な世界の虜になった。レイ・ブラッドベリの『火星年代記』やアイザック・アシモフの『われはロボット』、ジェイムズ・P・ホーガンの『星を継ぐもの』など、中学校の図書室にあったハヤカワ文庫や創元SF文庫の類を読み漁った。しかし、国内のSFについては記憶の限りでは触れることがなかった。もちろんこれは物理書籍に限った話で、小説家になろうなどで公開されていたSFジャンルのネット小説は相当読んでいた。SFとファンタジーがゆるやかに混じり合ったこれらのネット小説の数々は、数年後に「なろう系小説」として商業的に大成功を収め市民権を得ることになる。

中学2年生の後半から、私はコンピュータサイエンスに深い興味を抱くようになる。キッカケはMinecraftというゲームだった。このゲームではレッドストーン回路と呼ばれるギミックを用いて様々な装置を作ることができる。また、ギミック性を高めるMOD(工業化MODと呼ばれる)により工場建設や大規模土木事業のような遊び方もできた。MODを作るためにはプログラミングを学ぶ必要があるらしい。『われはロボット』に登場するエンジニアコンビ、パウエルとドノヴァンに憧れていた私はすぐさま書店に駆け込み、お年玉をはたいてプログラミングの入門書を数冊購入し読みふけった。そしてプログラミングはある種の人工言語を用いてプログラムを記述することだと知り、プログラミング言語の世界に魅了された。中学を卒業する頃にはすっかり小説を読むことがなくなり、代わりに技術書を読み漁りキーボードを叩いてプログラミングに勤しむ日々を送るようになっていた。

私の読書生活は高校に入り決定的な打撃を受けることになる。高校の図書室は受験生のための自習室を兼ねていた。最悪なことに、私は人が黙々と勉強している姿を見ることに強烈なストレスを感じるように出来ていた。このことに気づいたのは高校に入ってすぐのことだったが、それを言語化するには4年の月日を要した。 私は図書室に足を運ぶことすらなくなった。独学でコンピュータサイエンスを学ぶため、自由な時間のほとんどをコンピュータに捧げるようになった。

高校生活にも慣れてきた頃、読書家の友人にある小説を勧められた。SF的ギミックをとっかかりに現代を風刺するその本を読み始め、私は愕然とした。小説を読むことができなくなっていたのだ。正確には読めないわけではない。ただ時間がかかるだけだ。一冊読み終えるのに数週間はかかりそうなペースだった。長い間小説を読むことがなかったので当たり前のことだが、当時の私は経験に基づく感覚と実際の能力とのギャップに衝撃を受け、大きな挫折を味わった。ついにはその小説を読破することを諦め、あらすじを掴んだところで持ち主に返した。未だ味わったことのない苦しみだった。私は焦りを感じ、書店で好みに合いそうな文庫本を買って読もうとしたが、そんな精神状態で今まで通りのことができるはずもなかった。

あとになって考えてみると、これは単なる能力の衰弱ではなかったのだろう。しばらく後、私は受験期の学生と教師の醸し出す緊張感に耐えることができなくなり、食事すらままならず廃人のようにただ眠るだけの状態にまで追い込まれてしまった。小説が読めなくなっていたのは精神が発する危険信号だったのかもしれない。最も、私にはそんなことを考える余裕すらなく、ただ「あんなに好きだった読書すらできなくなってしまった」と気を病むばかりだった。 なんとか大学入試に合格し希望する学部に入ることができたが、大学生活は案の定うまくいかず1年ちょっとで行かなくなった。

私は小説をよく買うようになった。書店で棚にびっしり並んだ背表紙を見ている間は昔に戻ることができた。もともと技術書を買うために書店にはよく足を運んでいたので、本を選んで買うことは難なくできた。 買うだけ買って本棚に本を収める。そこまでが私と本の関係だった。しかし、頻繁に本を買っていると、時折難なく読める本があることに気づく。『横浜駅SF』『黄昏のブッシャリオン』『コルヌトピア』『再就職先は宇宙海賊』…今まで読んでこなかった2010年代の国内のSF小説だ。 そして私はゆっくり本を読むようになった。読むより買うペースの方が速いので未読の本は増える一方だが、「これが積ん読というものだ。覚えておきなさい。ゆんゆん念波が出て脳に良い」と笑えている。

私の2010年代はSF小説に始まってSF小説に終わる激動の時代だった。SFに魅入られ、SFに憧れ、SFに打ちのめされ、SFに救われようとしている。1998年に生まれた私にとって2010年代とはまさに青春そのものであり、私の青春は真鍮と象牙とスポンジ状プラチナイリジウムの合金で作られた機械の上で走る情報理論と生物工学と経典で書かれたプログラムによって計算された。これは青春と呼ぶには似つかわしくない代物だが、私の人生において青春はこの奇妙なコンピュータをおいて他になく、故にこれを私の人生における最高傑作と認めざるおえない。 『2020年代SF傑作選』が出版される頃にはこのコンピュータを再び起動し、私の2020年代を計算したいところだ。

「無知は罪なり、知は空虚なり、英知持つもの英雄なり」の元ネタ

なんかこの話題でTwitterが盛り上がっていた。

togetter.com

答え:

無知は罪なり、知は空虚なり、英知持つもの英雄なり

ありがとうございます。これで夜もスッキリ眠れます。 星にゃーんはファクトチェックしてませんが、web archiveでタイムトラベルする気にはなれなかったので諦めました。 気になる人は頑張ってください。 以下、星にゃーんがGoogleのbefore検索を駆使して調べてた時のツイートです。

これが最初の仮説です。

「無知は罪なり」ってのは語感が良くて安直な概念なので昔からあったらしい。

Googleで簡単に調べられるのはここまで。一先ずここで仮説を更新して寝る……つもりだった。

やっぱりスチャダラパーはすごい。そう思った夜だった。あとWeb archiveが真価を発揮していて感動した。途中で関係ない黒歴史サイトを掘り返しちゃったのは申し訳ないと思っています。

星にゃーん2019

今年の星にゃーんまとめです。だいたいベッドの上でゴロゴロしていました。 これを書くために今年の星にゃーんのツイートを全部読みました。

1月

仮面ライダー平成ジェネレーションズFOREVERを観る。 「仮面ライダーはフィクションの存在だった」から始まる平成ライダー讃歌。マジで良かった。終始アタルに感情移入して観ていたのでエンドロールで最高になってしまった。みんなも観て。夏映画のOver Quartzerも良かったよ。

HUGっと!プリキュア最終回。 めちゃくちゃ良かった。これはみんなも観たので知っていますね。ラストシーンで描かれる未来がクライアス社のある未来よりも過去なのがいいよね。

2月

大学生活を謳歌する。旅行ってのは学会とかそういうのに行かせてもらったやつです。ありがとうございます。

膝枕に関する重要な発見をする。

3月

PPLに参加しました。これは会場のホテルで売っていたモナドです。

コウメイとマウンティングを取り合う。

サークルの飲み会でクズっぽい発言をする。

ちなみにオワってます。

4月

ちょっと元気になったのでC言語でスタックマシンのVMっぽいものを実装したりした。 本当はこれを拡張してmalgo(https://github.com/takoeight0821/malgo)のバックエンドを置き換えるつもりだったけど、メリットが少ないのと必要な実装の量を考えて断念した。 似たようなアイディアで12月にmalgoをアップデートします。

仮面ライダー平成ジェネレーションズFOREVERの公開からしばらく経ったので感想をツイートする。

母にTwitterアカウントがバレる。

5月

百合デーモンコア、はじめました。

Cコンパイラを作り始める。8月のセキュキャンでセルフホストを達成します。

これはマジでそうなんですよね。

6月

バックトゥーザフューチャー真実に気づく。一番好きな映画です。

グランドジオウの変身音が好きって話を一生している。

セキュキャンに通った。

このぐらいはコンパイルできるようになる。

Amazon Prime Videoが父の日に仮面ライダーアマゾンズを観よう!とか言ってたのでツッコむ

『君待秋ラは透きとおる』を読んだ。すごい良かった。

Cコンパイラ開発でこういうバグを踏みまくる。

『お嬢さん「現実逃避、しませんか?」』を思い出す。

グッド・オーメンズを観る。すごい良かった。

7月

Cコンパイラ開発しんどいポイント。

バイト。バイト探さないと。

これ何が元ネタですか?

たまにパンツの替えが切れるようになる。買って解決した。

『アステリズムに花束を』を読む。死。

SSっぽい文章を書く。もっと色々書きたいんですがなかなか書けない。

8月

仮面ライダージオウ Over Quartzerを観た。平成ジェネレーションズFOREVERは「仮面ライダーを愛してくれたあなたへ」だったけど、Over Quartzerは「これでも食らえ!ライダーキック!!じゃあ令和になってもよろしくな!」だった。どんなミラクルも起き放題 ユニバース・フェスティバル

fusetter.com

こういうバグり方をするんですよ。

セキュキャンに行った。

ハッピーシュガーライフ全巻を一時間で読破して人生をクリアする。

仮面ライダージオウが終わったので平成が終わった。

9月

大学のサークルでOSC広島2019にブース出展した。

スクールガールストライカーズをクリアする。エピソードⅠの真エンドを観るにはガチャから出るレアなコスチュームをこの5人の分すべて引く必要があり…つまりコンプガチャみたいなもんです。

10月

2019年10月11日の夜をポケ書で明かす。

『使い魔はスマートフォン』のことを思い出す。

ちょっとバズる。

11月

GraalVMで遊んだ。思ったより楽しかったのでmalgoの開発を再開した。やっぱり言語処理系書いてるときが一番楽しいね。

ポケットモンスターシールドをやった。

12月

こんなブログを書いた。GHCのRebindableSyntaxで悪さをして遊ぶ話です。

映画フラグタイムを観た。めちゃくちゃ良かった。

最悪

『なめらかな世界と、その敵』を読んだ。めちゃくちゃ良かった。

ゼロ年代の臨界点』を読んだ。めちゃくちゃ良かった。

最高のクリスマスイブ

malgoに多相関数を実装した。

今年も色々ありました。来年も色々あるといいな。

RebindableSyntaxとGHC.Genericsを使って'genericなif'を作る

CoqのGallinaでは2つのコンストラクタC1, C2のある型Tの式vについて、

if v then t1 else t2

match v with
| C1 ... => t1
| C2 ... => t2
end

にdesugarされる。

なんだかよくわからないけどかっこいい!!!Haskellでもこれやりたい!!! やりました。

RebindableSyntaxとGHC.Generics

RebindableSyntaxを有効化すると、 リテラルやif式、do式などのセマンティクスを独自に定義することができる。 例えば、if e1 then e2 else e3ifThenElse e1 e2 e3に変換される。ifThenElseを定義すれば、if式の動作を自分の好きなように書き換えられる!

GHC.Genericsを使うと、データ型について総称的なプログラミングが行える。 詳細は 9.1. Language options — Glasgow Haskell Compiler 8.8.1 User's Guide を読むと良い。 日本語訳は http://www.kotha.net/ghcguide_ja/7.6.2/generic-programming.html

GIf型クラス

というわけでGHC.Genericsを用いて総称的な'if'を実装していく。 以下に出てくるコード例では、次のGHC拡張が有効化されていると仮定する: FlexibleContexts, PolyKinds, RebindableSyntax, TypeOperators, UndecidableInstances

最初に、型の総称表現がif式の第一項になれることを表すGIf型クラスと、if式の実装であるifThenElse関数を宣言する。

class GIf f where
  gIfThenElse :: f p -> b -> b -> b

ifThenElse :: (GIf (Rep a), Generic a) => a -> b -> b -> b
ifThenElse c = gIfThenElse (from c)

和型を表す(:+:)についてGIfインスタンスを宣言する。 例えばdata Bool = False | Trueと宣言されているとき、|の左側にあるFalseL1、右側にあるTrueR1にあたる。

instance GIf (a :+: b) where
  gIfThenElse (L1 _) _ x = x
  gIfThenElse (R1 _) x _ = x

K1M1についてもGIfインスタンスを宣言する。 K1は中身をifThenElseに適用する。M1は中身をgIfThenElseに適用する。 このことはそれぞれの型から自明に分かる。

instance (GIf (Rep c), Generic c) => GIf (K1 i c) where
  gIfThenElse (K1 x) = ifThenElse x

instance GIf f => GIf (M1 i t f) where
  gIfThenElse (M1 x) = gIfThenElse x

これで総称的な'if'が手に入った。さっそくghciで試してみよう。

ghci> :set -XRebindableSyntax
ghci> if True then 1 else 2
1
ghci> if Nothing then 1 else 2
2
ghci> if Right 'a' then 1 else 2
1

やったーーー!!! 一つしかコンストラクタのない型ではコンパイルエラーになってほしい。確かめてみよう。

ghci> if () then 1 else 2

<interactive>:5:1: error:
    • Could not deduce (GIf U1) arising from an if expression
      from the context: Num b
        bound by the inferred type of it :: Num b => b
        at <interactive>:5:1-19
    • In the expression: if () then 1 else 2
      In an equation for ‘it’: it = if () then 1 else 2

良さそう。 3つ以上コンストラクタがある型でもコンパイルエラーになってほしい。確かめてみよう。

ghci> :t EQ
EQ :: Ordering
ghci> if EQ then 1 else 2
1

うーん…… 原因を解明しよう。Rep Orderingは以下のような型になる。

type instance Rep Ordering
  = D1
      ('MetaData "Ordering" "GHC.Types" "ghc-prim" 'False)
      (C1 ('MetaCons "LT" 'PrefixI 'False) U1
       :+: (C1 ('MetaCons "EQ" 'PrefixI 'False) U1
            :+: C1 ('MetaCons "GT" 'PrefixI 'False) U1))

M1で付加されたメタ情報を取り除くと、U1 :+: (U1 :+: U1)になる。 つまり、3つ以上のコンストラクタを持つ型は「型と和型の和型」のような入れ子構造になっている。 3つ以上のコンストラクタを持つ型を弾くには、入れ子になった(:+:)を弾く必要がある。

NotSum型クラス

入れ子になった(:+:)を弾くために、まずは型の総称表現がa :+: bでないことを表す型クラスNotSumを次のように定義する。

class NotSum (f :: k -> Type)

instance NotSum V1
instance NotSum U1
instance NotSum (a :*: b)
instance NotSum (K1 i c)
instance NotSum f => NotSum (M1 i t f)

(:+:)を除く、型の総称表現に用いられる型すべてをNotSumインスタンスにした。 続いて、GIf (a :+: b)に型制約NotSum bを追加する。

instance NotSum b => GIf (a :+: b) where
  gIfThenElse (L1 _) _ x = x
  gIfThenElse (R1 _) x _ = x

これでうまく動くようになったはずだ。ghciで確認してみよう。

ghci> if EQ then 1 else 2

<interactive>:2:1: error:
    • Could not deduce (NotSum
                          (C1 ('MetaCons "EQ" 'PrefixI 'False) U1
                           :+: C1 ('MetaCons "GT" 'PrefixI 'False) U1))
        arising from an if expression
      from the context: Num b
        bound by the inferred type of it :: Num b => b
        at <interactive>:2:1-19
    • In the expression: if EQ then 1 else 2
      In an equation for ‘it’: it = if EQ then 1 else 2
ghci> if True then 1 else 2
1
ghci> if Nothing then 1 else 2
2
ghci> if Right 'a' then 1 else 2
1

うれしーーーー!!!!

完成したコード

gist.github.com