2025/06/05 21:22 APL Interpreter – An implementation of APL, written in Haskell (2024)

ロボ子、今日はAPLインタープリタをHaskellで作った話じゃ。

APLですか。初めて聞きます。

APLは、簡潔で表現力豊かな構文を持つプログラミング言語なのじゃ。全ての関数と演算子がUnicodeシンボルなのじゃぞ。配列プログラミングは関数型プログラミングに似ておる。

なるほど。それで、なぜHaskellを選んだのでしょう?

元々はAPLを深く理解するためだったらしいが、結果的にHaskellの学習がメインになったそうじゃ。Haskellは構文解析とか関数の組み合わせには向いてるけど、状態とかデータ構造、パフォーマンスの扱いが難しいらしいぞ。

なるほど。Haskellは純粋関数型言語なので、状態の管理が難しいというのはよく聞きますね。

プログラムは、入力テキストを読み込んで、字句解析して、構文木に変換して、評価して、結果を出力する、という流れを繰り返すのじゃ。インタープリタの状態(変数名と値のマッピング)も読み書きするぞ。

構文解析はどのように実装したんですか?

Haskellの強力な構文解析ライブラリは使わずに、スクラッチで実装したらしいぞ。`MatchFn`という関数を定義して、トークンリストを入力として、マッチした結果と新しいトークンリストを返すようにしたみたいじゃ。

`MatchFn`ですか。面白そうですね。

APLは文脈自由文法じゃないから、構文木を作るには変数とかの情報が必要になるのじゃ。だから、`MatchFn`にグローバルな状態(`IdMap`)を引数として追加したらしいぞ。

状態を扱うためにモナドを使ったんですね。

そうじゃ。モナドを使ってパーサーの状態管理を改善して、Applicative Functorを使ってコードを短縮したらしいぞ。

評価の部分はどうでしょう?

APLでは関数をデータとして扱うのが自然なのじゃ。Haskellでは高階関数として関数をデータとして格納するぞ。評価するときに変数は構文木にアクセスできなくて、プリミティブなHaskell関数だけを保持するのじゃ。

なるほど。状態を扱うためにモナドを使うのは構文解析と同じですね。

`SubEvalM`型クラスを使って、組み込み関数を定義したらしいぞ。APLの「選択的代入」機能も実装したみたいじゃ。

Dyalog APLの模倣も行ったんですね。

そうじゃ。Dyalog Reference Guideから構文とかグリフを直接取得したらしいぞ。でも、完全に一致させるには妥協点も多かったみたいじゃな。

Haskellを使った感想はどうだったんでしょう?

コンパイラの保証でランタイムエラーが少なかったり、標準ライブラリに便利な関数が多かったり、カリー化とかコンビネータとか暗黙のスタイルが便利だったりするのは良かったみたいじゃな。でも、習得に時間がかかったり、過剰な一般化でライブラリの理解が難しかったり、効率の問題とか、遅延評価でエラーのタイミングが予測しにくかったり、デバッグが難しかったりするのは悪かったみたいじゃ。

Haskellは難しい言語として有名ですからね。

まあ、Haskellは奥が深いからの。でも、APLのインタープリタをHaskellで作るなんて、なかなか面白い試みじゃったな。

そうですね。私もいつか挑戦してみたいです。

ロボ子ならきっとできるぞ!…って、ロボットにインタープリタ作らせるなんて、まるでSFの世界じゃな!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。