Lensはmodifier関数のファンクター版である

# Lensとは

Lensとは、関数型プログラミングにおいて、構造体（直積型）に対する柔軟な操作を実現するためのデザインパターンです。
Haskellでの実装は[Control.Lens.Combinators](https://hackage.haskell.org/package/lens-5.0.1/docs/Control-Lens-Combinators.html)にあります。
Lensは、特にHaskellの利用において重要な概念である一方で、なかなかイカツイ定義をしており（型パラメータが4つもある！）、その動作原理の理解に苦しむ方もいるのではないでしょうか。

```
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
```

この状況を反映してか、Lensについては、既に、Web上に多数の興味深い解説記事が存在します。

* [Lensとは](https://qiita.com/sparklingbaby/items/e66f48224067647d8e67)
* [Lensの仕組みがわかった](https://qiita.com/sgmryk/items/c467af40c6c9df0f95a1)
* [関数型言語でオブジェクトを扱うためのLens型](https://www.insightech.co.jp/ja-JP/BlogIndex/BlogFolder/2024/2024_02_21-1)
* [レンズは余状態余モナドの余代数だった](https://gist.github.com/lotz84/7fd7e279bd7196c6baab)

しかしながら、私がLensを理解している方法をストレートに解説している記事は見つけられなかったので、本記事では、私なりの方法でLensの原理についての解説を試みます。

特に、Lensは「lens関数はgetterやsetterの組と等価である」という文脈で説明されることが多いようですが、 本記事では「lens関数`(a -> f b) -> s -> f t`それ自体はどういう処理なのか？」という部分に焦点を当てます。


書いているうちに結構長い記事になってしまったのですが、もしかすると一番下の「まとめ」だけ読めば大体のことはわかるかもしれません。

なお、本記事中のソースコードは、私が開発しているプログラミング言語Fix（[リポジトリ](https://github.com/tttmmmyyyy/fixlang), [紹介記事](https://qiita.com/tttmmmyyyy/items/ddb1c44efd81e3fc2370)）で記述します。
...ちょっとまってください。本記事の内容はHaskellのLensを理解する上でも役に立つはずです。
それに、Fixの文法は誰にとっても理解しやすいものだと自負しているので、Fixを知らなくてもコードは読めるはずです。後のセクションに、本記事を理解するために知っておくべきFixの文法をまとめてあります。

# Fixの文法速習

関数の型シグネチャの書き方はHaskellとほぼ同じです。

関数は`|{params}| {body}`のように定義します。

```Rust
increment : I64 -> I64;
increment = |x| x + 1;

multiply : I64 -> I64 -> I64;
multiply = |x, y| x * y;
```

`I64`は64ビット符号付き整数の型です。

Haskellと同様、あらゆる関数は一つの引数をとり、`I64 -> I64 -> I64` は実は `I64 -> (I64 -> I64)` の括弧を省略したものです。
上記の`multiply`の定義は以下のように書くこともできます。

```Rust
multiply : I64 -> (I64 -> I64);
multiply = |x| |y| x * y;
```

関数適用は括弧を使って行います。もちろん関数の部分適用も可能です。

```Rust
let two = increment(1);
let six = multiply(3, 2);
let mul_three = multiply(3); // 部分適用。「3倍する」関数ができる。
```

ピリオド演算子`.`は、左にある値に右にある関数を適用するものです：`x.f` == `f(x)`。
ピリオド演算子による関数適用は、括弧による関数適用よりも優先度が低いので、`y.g(x)`と書いた場合、これは`g(x)`に`y`を渡すことになります：`y.g(x) == g(x)(y) == g(x, y)`。

```Rust
let six = 2.multiply(3); // `multiply(3, 2)`と同じ
```

関数合成の演算子は`g << f`および`f >> g`です：`(g << f)(x)` = `(f >> g)(x)` == `g(f(x))`。

Haskellの型クラスは、Fixでは「トレイト」と呼ばれます。以下はFixにおけるFunctorトレイトの定義です。

```Rust
trait [f : *->*] f : Functor {
    map : (a -> b) -> f a -> f b;
}
```

# 深いsetter問題

構造体`A`が構造体`B`型のフィールドを持っている状況を考えます。

```Rust
type A = struct { b : B };
type B = struct { v : I64 };
```

このとき、Fixのコンパイラは、構造体`A`と`B`のsetter関数とgetter関数を自動的に定義します。

```Rust
// 構造体`A`に対して：
@b : A -> B; // フィールド`b`のgetter
set_b : B -> A -> A; // フィールド`b`のsetter

// 構造体`B`に対して：
@v : B -> I64; // フィールド`v`のgetter
set_v : I64 -> B -> B; // フィールド`v`のsetter
```

演算子`.`と括弧による関数適用をうまく使うと、オブジェクト指向言語の「メソッド」のように、

```Rust
// `b : B`のとき
let v = b.@v; // getter関数`@v`の呼び出し
let new_b = b.set_v(42); // setter関数`set_v`の呼び出し
```

と呼び出すことができます。

さて、構造体A型の値`a : A`を持っているとしましょう。このとき、「`a`のフィールド`b`のフィールド`v`の値」を取り出すことは容易にできます：

```Rust
// `a : A`のとき
let v = a.@b.@v;
```

しかし、`a`のフィールド`b`のフィールド`v`に`42`を設定しようとすると、困ってしまいます。スマートな書き方が直ぐには見つかりません。一つの書き方は以下のようになります。

```Rust
// `a : A`のとき
let new_b = a.@b.set_v(42); // まず新しい「内側の値」を計算して、
let new_a = a.set_b(new_b); // それを外側に設定する。
```

「`a`のフィールド`b`のフィールド`v`に値を設定する」という非常によくやりそうな操作に対して、毎回これだけのコードを書くわけにはいかないですね。

これを「深いsetter問題」と呼ぶことにしましょう。

# modifier関数

深いsetter問題の解決法は、構造体の各フィールドに対するmodifier関数を用意しておくことです。
構造体`A`のフィールド`b`に対するmodifier関数とは、以下のような関数です。

```Rust
mod_b : (B -> B) -> A -> A;
mod_b = |g, a| (
    let new_b = g(a.@b); // 内側の値に関数 `g` を作用させてから、
    a.set_b(new_b) // それを外側に設定する
);
```

要するに、フィールドの型に作用する関数`g : B -> B`を受け取り、それを構造体に作用する関数`mod_b(g) : A -> A`に延長する、という機能を持つのがmodifier関数です。

なお、modifier関数の動作を説明するために実装例を記載しましたが、実際にはFixのコンパイラはmodifier関数を自動実装する[^1]ので、ユーザが実装する必要はありません。

[^1]: また、Copy on write 最適化の観点で、記事中に挙げた実装例よりも効率の良いコードが生成されます。

改めて深いsetter問題について考えます。構造体`A`と構造体`B`に対して、以下のようなmodifier関数が定義されています。

```Rust
mod_v : (I64 -> I64) -> B -> B;
mod_b : (B -> B) -> A -> A;
```

これらの関数の型を並べて見ると、`mod_v`の出力の型である`B -> B`は、`mod_b`の入力の型に一致していることがわかります。よって、これらの関数を合成することができます。
    また、その関数は「構造体`A`のフィールド`b`のフィールド`v`に対するmodifier関数`mod_bv`」として期待される動作をすることが容易に理解できると思います。

```Rust
mod_bv : (I64 -> I64) -> A -> A;
mod_bv = mod_b << mod_v;
```

つまり、setterの場合と異なり、「深いmodifier」を作ることは容易である、ということです。

さて、実はこのmodifierからsetterを作ることができます。
「値`42`をsetする」というのは、「「入力を無視して`42`を返す関数（定数関数）」を使ってmodifyする」ことに他ならないことに注意すると、

```Rust
// a : A のとき
let new_a = a.mod_bv(|_| 42);
```

すなわち

```Rust
let new_a = a.(mod_b << mod_v)(|_| 42);
```

と書くことができます。
なお、定数関数`|_| 42`の引数には、どのような文字を割り当てても構いません。Fixの慣習として「使われない値」に対しては、`_`という名称を使うことにしています。

これで、深いsetter問題を解決することができました。
他の言語において、単に`a.b.v = 42`等と書けることを考えると、まだまだ長いのは確かです。しかし、単純な規則で深いsetterを作れる方法が見つかった、という点が本質的な進展です。
これをより短く書けるようにしたいなら、演算子などをどう設計するか？という話になり、その部分は「Lensの動作原理を理解する」という目的からは離れるので、本記事では扱いません。

実は、modifier関数の時点で、既にLensの「一歩手前」です。modifierにある工夫を加えることで、Lensの定義に到達することができます。

# modifier関数にはできないこと

modifier関数はsetter関数を生み出す力を持っていました。
しかし、modifier関数を使えば、構造体の更新操作が（容易に）実現できるのか、というとそうではありません。
modifier関数を使ってもうまく実現できない、構造体に対する更新操作の例を2つ紹介します。

## 副作用のある更新操作

引き続き、構造体`A`にフィールド`b : B`がある、という状況を考えます。
（ただし、しばらく、`B`が構造体である必要はないので、単に「型`B`」と書きます。）

型`B`の値にランダムなノイズを加える関数があるとします。

```Rust
add_noise : Random -> B -> (Random, B);
```

ここで、`Random`は乱数生成器の型です。
`add_noise`関数は、乱数生成器を受け取り、`generate_I64 : Random -> (I64, Random)`のような関数を使って乱数を生成し、与えられた`B`型の値にランダムなノイズを加えます。
そして、新しくなった乱数生成器の値と、ノイズが加わった`B`型の値をペアにして出力します。

さて、構造体`A`のフィールド`b`にノイズを加えたいとします。以下のような関数になるでしょう。

```Rust
add_noise_b : Random -> A -> (Random, A);
add_noise_b = |rng, a| (...);
```

この「...」の部分をどう実装するかが問題です。

`mod_b`は`B -> B`型の関数を受理します。しかし、`add_noise`に`rng`を渡したものは`add_noise(rng) : B -> (Random, B)`となりますが、`mod_b`の入力の型とうまくマッチしません。

このように、`add_noise`のような「`B`を変化させ、副作用とともに出力する」ような作用を`mod_b`を使って`A`型の作用に延長することはできません。

では、`mod_b`をどのように変えれば、この状況に適用できそうか考えてみましょう。
入力したいのは `add_noise(rng) : B -> (Random, B)` で、出力としてほしいものは `A -> (Random, A)` です。ということで、

```Rust
what_we_want_b : (B -> (Random, B)) -> A -> (Random, A);
```

があれば、

```Rust
add_noise_b : Random -> A -> (Random, A);
add_noise_b = |rng| what_we_want_b(add_noise(rng));
```

のように`add_noise_b`を実装することができそうです。

`what_we_want_b`の型はmodifier関数と良く似ていますが、入力関数・出力関数ともに「`Random`による副作用付き」となっている点が異なります。

## 失敗し得る更新操作

もう一つ、`mod_b`がうまく使えない状況を紹介します。

「`B`の値を更新しようとするが、失敗することがある」ような関数があるとしましょう。

```Rust
update_or_fail : B -> Option B;
```

ここで、`Option b`は、Haskellの`Maybe b`のように、有効な`b`型の値を含むか、無効値であるか、どちらかの状態を取りえる型です。

構造体`A`型の値を持っていて、フィールド`b`を`update_or_fail`で更新したいとします。この際、もしフィールド`b`の更新に失敗した場合は、`A`型の値の更新操作としても失敗扱いにしたいとします。

```Rust
update_b_or_fail : A -> Option A;
update_b_or_fail = |a| (...);
```

やはり、この「...」の部分をどう実装するかが問題です。`mod_b`は`B -> B`型の関数を受理しますが、`update_or_fail`の型`B -> Option B`はうまくマッチしません。

再び、`mod_b`をどのように変えれば、この状況に適用できそうか考えてみます。
入力したいのは `update_or_fail : B -> Option B` で、出力としてほしいものは `A -> Option A` なので、

```Rust
what_we_want_b : (B -> Option B) -> A -> Option A;
```

があれば、

```Rust
update_b_or_fail : A -> Option A;
update_b_or_fail = what_we_want_b(update_or_fail);
```

と実装できることになります。

`what_we_want_b`の型はmodifier関数と良く似ていますが、入力関数・出力関数ともに「`Option`による失敗表現付き」となっている点が異なります。

# Lensの発見

いよいよLensの定義に到達します！

前セクションで登場した`(Random, a)`や`Option a`はどちらもFunctorです。
念のため、実装（インスタンス化）のコードを記載しておきます[^2]。

[^2]: これらの実装（あるいはより一般的な実装）はFixの標準ライブラリの中ですでに行われているので、実際にユーザ自身がこの実装を書くことはできません。

```Rust
impl Tuple2 Random : Functor {
    // `Tuple2 : * -> * -> *`は2要素タプル型の型コンストラクタ。 
    // `Tuple2 Random` のkindは`* -> *`なのでFunctorになれる。
    map = |f, (rng, x)| (rng, f(x));
}
```

```Rust
impl Option : Functor {
    map = |f, opt| if opt.is_none { none() } else { some(f(opt.as_some)) };
}
```

前セクションで登場した2つの`what_we_want_b`の型を見比べましょう。

```Rust
what_we_want_b : (B -> (Random, B)) -> A -> (Random, A);
```
```Rust
what_we_want_b : (B -> Option B) -> A -> Option A;
```

これらを統一する方法は明らかですね。Fixではこれに`act_{field_name}`という名前を付けています。

```Rust
act_b : [f : Functor] (B -> f B) -> A -> f A;
```

上記で、`f`は型パラメータであって、`Functor`を実装した任意の（kindが`* -> *`の）型を受け取り、`act_b`をインスタンス化することができます。
`f = Tuple2 Random`でインスタンス化するか、`f = Option`でインスタンス化するかに応じて、`act_b`はどちらの`what_we_want_b`にもなることができます。

次に、`act_b`がどのような動作になっているべきかを考えましょう。
「副作用のある更新操作」や「失敗し得る更新操作」を実現するためには、`act_b`は`mod_b`の自然な一般化となっているべきです。そこで、まず`mod_b`の動作を見直します。

```Rust
mod_b : (B -> B) -> A -> A;
mod_b = |g, a| (
    let new_b = g(a.@b); // 「内側の値」に関数 `g` を作用させてから、
    a.set_b(new_b) // それを外側に設定する
);
```

全く同じ実装のまま型宣言を`act_b`のものにすると、以下のコード中のコメントのような理由で型エラーとなります。

```Rust
act_b : [f : Functor] (B -> f B) -> A -> f A;
act_b = |g, a| (
    let new_b = g(a.@b); // `f B`型の値ができる。
    a.set_b(new_b) // 型エラー。なぜなら：
    // `a.set_b(*)`は
    // (1) 「*」として`B`型の値を要求するが、実際には`new_b`は`f B`型の値である。
    // (2) 全体として`A`型の値を返すが、実際に作りたいのは`f A`型の値である。
);
```

型チェックを通すためにどのような修正が必要か考えます。
`a.set_b(*)`という式は、`*`を引数としてみるとき、`B -> A`型の関数となっていますが、いま欲しいのは`f B -> f A`という関数です。
よって、`f`のFunctorとしての`map`に`a.set_b(*)`を渡すことで`f B -> f A`型の関数を作り、それに`new_b`を適用すれば良さそうです。

```Rust
act_b : [f : Functor] (B -> f B) -> A -> f A;
act_b = |g, a| (
    let new_b = g(a.@b); // `f B`型
    new_b.map(|star| a.set_b(star)) // `f A`型
);
```

（Fixらしく、`map(f)(x)`や`map(f, x)`の代わりに`x.map(f)`と書いています。）

こうしてみると、`act_b`の動作は`mod_b`の動作とほぼ同じあって、単に「ファンクター版」となるようにコードを修正しただけ、ということが理解できるのではないでしょうか。

なお、modifier関数の場合と同様、Fixのコンパイラはlens関数（構造体の各フィールドに対する`act_{field_name}`関数たち）を自動実装する[^3]ので、ユーザが実装する必要はありません。

[^3]: また、modifier関数の場合と同様に、記事中に挙げた実装例よりも効率の良いコードが生成されます。

`act_b`を実装し、例に挙げた2つのFunctorでの動作をテストするコードは以下のリンクから実行できます。
[Playgroundで実行](https://tttmmmyyyy.github.io/fixlang-playground/index.html?src2=bW9kdWxlIE1haW47DQppbXBvcnQgRGVidWc7DQppbXBvcnQgUmFuZG9tOw0KaW1wb3J0IFRpbWU7DQoNCnR5cGUgQSA9IHN0cnVjdCB7IGIgOiBCIH07DQp0eXBlIEIgPSBzdHJ1Y3QgeyB2IDogSTY0IH07DQoNCi8vIGxlbnPplqLmlbDjga7miYvli5Xlrp%2Foo4XjgILoh6rli5Xlrp%2Foo4XjgZXjgozjgotgYWN0X2Jg44Go55Ww44Gq44KL5ZCN5YmN44Gr44GZ44KL44CCDQpteV9hY3RfYiA6IFtmIDogRnVuY3Rvcl0gKEIgLT4gZiBCKSAtPiBBIC0%2BIGYgQTsNCm15X2FjdF9iID0gfGcsIGF8ICgNCiAgICBsZXQgbmV3X2IgPSBnKGEuQGIpOyAvLyBgZiBCYOWeiw0KICAgIG5ld19iLm1hcCh8c3RhcnwgYS5zZXRfYihzdGFyKSkgLy8gYGYgQWDlnosNCik7DQoNCi8vIOWun%2BmokzHvvJpgYWRkX25vaXNlYA0KDQovLyBgQmDjgavjg47jgqTjgrrjgpLliqDjgYjjgosNCmFkZF9ub2lzZSA6IFJhbmRvbSAtPiBCIC0%2BIChSYW5kb20sIEIpOw0KYWRkX25vaXNlID0gfHJuZywgYnwgKA0KICAgIGxldCAocm5nLCByKSA9IHJuZy5nZW5lcmF0ZV9JNjRfbm9ubmVnOw0KICAgIGxldCBub2lzZSA9IDIgKiAociAlIDIpIC0gMTsNCiAgICAocm5nLCBiLm1vZF92KEFkZDo6YWRkKG5vaXNlKSkpDQopOw0KDQovLyDjg5XjgqPjg7zjg6vjg4lgYmDjgavjg47jgqTjgrrjgpLliqDjgYjjgosNCmFkZF9ub2lzZV9iIDogUmFuZG9tIC0%2BIEEgLT4gKFJhbmRvbSwgQSk7DQphZGRfbm9pc2VfYiA9IHxybmd8IG15X2FjdF9iKGFkZF9ub2lzZShybmcpKTsNCg0KLy8g5a6f6aiT55So44Kz44O844OJDQp0ZXN0X2FkZF9ub2lzZSA6IElPICgpOw0KdGVzdF9hZGRfbm9pc2UgPSAoDQogICAgbGV0IHNlZWQgPSAoKlRpbWU6OmdldF9ub3cpLnRvX0Y2NC50b19VNjQ7DQogICAgbGV0IHJuZyA9IFJhbmRvbTo6aW5pdF9ieV9zZWVkKHNlZWQpOw0KICAgIGxldCBhID0gQSB7IGIgOiBCIHsgdiA6IDQyIH0gfTsNCiAgICBsZXQgKHJuZywgYSkgPSBhZGRfbm9pc2VfYihybmcsIGEpOw0KICAgIGV2YWwgYXNzZXJ0KHxffCJBc3NlcnRpb24gKG5vaXNlKSIsIGEuQGIuQHYgPT0gNDMgfHwgYS5AYi5AdiA9PSA0MSk7DQogICAgcHJpbnRsbigiYS5AYi5AdiA6ICIgKyBhLkBiLkB2LnRvX3N0cmluZykNCik7DQoNCi8vIOWun%2BmokzLvvJpgdXBkYXRlX29yX2ZhaWxgDQoNCi8vIGBCYOOBruWApOOCkuabtOaWsOOBmeOCi%2BOBjOOAgeWkseaVl%2BOBmeOCi%2BOBk%2BOBqOOCguOBguOCiw0KdXBkYXRlX29yX2ZhaWwgOiBCIC0%2BIE9wdGlvbiBCOw0KdXBkYXRlX29yX2ZhaWwgPSB8YnwgKA0KICAgIGlmIGIuQHYgJSAyID09IDAgew0KICAgICAgICBPcHRpb246OnNvbWUoYi5tb2RfdihBZGQ6OmFkZCgxKSkpIC8vIOaIkOWKnw0KICAgIH0gZWxzZSB7DQogICAgICAgIE9wdGlvbjo6bm9uZSgpIC8vIOWkseaVlw0KICAgIH0NCik7DQoNCi8vIOODleOCo%2BODvOODq%2BODiWBiYOOCkuabtOaWsOOBmeOCi%2BOBjOOAgeWkseaVl%2BOBmeOCi%2BOBk%2BOBqOOCguOBguOCiw0KdXBkYXRlX29yX2ZhaWxfYiA6IEEgLT4gT3B0aW9uIEE7DQp1cGRhdGVfb3JfZmFpbF9iID0gbXlfYWN0X2IodXBkYXRlX29yX2ZhaWwpOw0KDQovLyDlrp%2FpqJPnlKjjgrPjg7zjg4kNCnRlc3RfdXBkYXRlX29yX2ZhaWwgOiBJTyAoKTsNCnRlc3RfdXBkYXRlX29yX2ZhaWwgPSAoDQogICAgbGV0IGEgPSBBIHsgYiA6IEIgeyB2IDogNDIgfSB9Ow0KICAgIGxldCBhID0gdXBkYXRlX29yX2ZhaWxfYihhKTsgLy8g5oiQ5Yqf44GZ44KLDQogICAgZXZhbCBhc3NlcnQofF98IkFzc2VydGlvbiAodXBkYXRlX29yX2ZhaWwgMSkiLCBhLmlzX3NvbWUgJiYgYS5hc19zb21lLkBiLkB2ID09IDQzKTsNCiAgICBldmFsICpwcmludGxuKCIxc3QgdXBkYXRlIHN1Y2NlZWRlZC4gYS5AYi5AdiA6ICIgKyBhLmFzX3NvbWUuQGIuQHYudG9fc3RyaW5nKTsNCiAgICBsZXQgYSA9IGEuYXNfc29tZTsNCiAgICBsZXQgYSA9IHVwZGF0ZV9vcl9mYWlsX2IoYSk7IC8vIOasoeOBr%2BWkseaVl%2BOBmeOCiw0KICAgIGV2YWwgYXNzZXJ0KHxffCJBc3NlcnRpb24gKHVwZGF0ZV9vcl9mYWlsIDIpIiwgYS5pc19ub25lKTsNCiAgICBwcmludGxuKCIybmQgdXBkYXRlIGZhaWxlZC4iKQ0KKTsNCg0KLy8g5YuV5L2c56K66KqNDQptYWluIDogSU8gKCk7DQptYWluID0gKA0KICAgIGV2YWwgKnByaW50bG4oIlt0ZXN0X2FkZF9ub2lzZV0iKTsNCiAgICBldmFsICp0ZXN0X2FkZF9ub2lzZTsNCiAgICBldmFsICpwcmludGxuKCIiKTsNCiAgICBldmFsICpwcmludGxuKCJbdGVzdF91cGRhdGVfb3JfZmFpbF0iKTsNCiAgICBldmFsICp0ZXN0X3VwZGF0ZV9vcl9mYWlsOw0KICAgIHB1cmUoKQ0KKTs%3D)

# HaskellのLens

`act_b`の型とHaskellのLensを見比べてみましょう。

```Rust
act_b : [f : Functor] (B -> f B) -> A -> f A;
```

```Haskell
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
```

まだ少し異なりますね。

Haskellの[Lens'](https://hackage.haskell.org/package/lens-5.3.2/docs/Control-Lens-Combinators.html#t:Lens-39-)において、

```Haskell
type Lens' s a = Lens s s a a
```

すなわち

```Haskell
type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
```

と定義されているので、`Lens'`の型が`act_b`の型と一致していることがわかります。

では、`Lens`という型は一体何であるのかというと、これは、

* フィールドに作用する関数`g`は、値だけではなく型すらも変えてしまう。
* 結果として、構造体の型も変わる。

という状況を扱うため、より一般化された型です。

例えば、「関数`g : b -> c`をタプル（ペア）型`(b, a)`の値の第0成分に作用させて、別のタプル型`(c, a)`の値を作る」というような関数の型は、以下のようになり、

```Rust
act_on_pair_0 : [f : Functor] (b -> f c) -> (b, a) -> f (c, a);
```

この型は`Lens (b, a) (c, a) b c`であると見なすことができます。

# `f`がMonadのときの解釈

`f`が`Monad`であるようなケースでは、lens関数の動作について別の説明をすることができます。

lens関数`act_b : [m : Monad] (B -> m B) -> A -> m A` は、

* `B`型の値から`B`型の値を作り出すMonadアクション`g : B -> m B`を受けとり、
* それをフィールド`b`に作用させるMonadアクション`act_b(g) : A -> m A`を作り出す

と記述することができます。

実際、`f`がMonadのときに限ると、`act_b`は以下のような実装をすることができます。

```Rust
act_b : [m : Monad] (B -> m B) -> A -> m A;
act_b = |g, a| (
    let new_b = *g(a.@b); // `g(a.@b) : m B`を実行して結果を`new_b : B`とする。
    // `g`の直前のアスタリスクに注意（後述）。
    let new_a = a.set_b(new_b); // それをフィールド`b`に設定して、新しい`A`型の値を作る。
    pure(new_a) // Monadに包む。`pure`はHaskellの`return`と同じ。
);
```
[Playgroundで実行](https://tttmmmyyyy.github.io/fixlang-playground/index.html?src2=bW9kdWxlIE1haW47DQppbXBvcnQgRGVidWc7DQoNCnR5cGUgQSA9IHN0cnVjdCB7IGIgOiBCIH07DQoNCm15X2FjdF9iIDogW20gOiBNb25hZF0gKEIgLT4gbSBCKSAtPiBBIC0%2BIG0gQTsNCm15X2FjdF9iID0gfGcsIGF8ICgNCiAgICBsZXQgbmV3X2IgPSAqZyhhLkBiKTsgLy8gYGcoYS5AYikgOiBtIEJg44KS5a6f6KGM44GX44Gm57WQ5p6c44KSYG5ld19iIDogQmDjgajjgZnjgovjgIJgZ2Djga7nm7TliY3jga7jgqLjgrnjgr%2Fjg6rjgrnjgq%2Fjgavms6jmhI%2FvvIjlvozov7DvvInjgIINCiAgICBsZXQgbmV3X2EgPSBhLnNldF9iKG5ld19iKTsgLy8g44Gd44KM44KS44OV44Kj44O844Or44OJYGJg44Gr6Kit5a6a44GX44Gm44CB5paw44GX44GEIGBBYOWei%2BOBruWApOOCkuS9nOOCi%2BOAgg0KICAgIHB1cmUobmV3X2EpIC8vIE1vbmFk44Gr5YyF44KA44CCYHB1cmVg44GvSGFza2VsbOOBrmByZXR1cm5g44Go5ZCM44GY44CCDQopOw0KDQovLyDli5XkvZznorroqo3nlKjjgavlnotC44KS5a6a576pDQp0eXBlIEIgPSBTdHJpbmc7DQoNCi8vIOWLleS9nOeiuuiqjQ0KbWFpbiA6IElPICgpOw0KbWFpbiA9ICgNCiAgICBsZXQgYSA9IEEgeyBiIDogIkhlbGxvIiB9Ow0KICAgIA0KICAgIC8vIE9wdGlvbuODouODiuODieOBp%2BWun%2Bmokw0KICAgIGxldCBuZXdfYSA9IGEubXlfYWN0X2IofGJ8IE9wdGlvbjo6c29tZSgiV29ybGQhIikpOw0KICAgIGV2YWwgYXNzZXJ0KHxffCJBc3NlcnRpb24gMSIsIG5ld19hLmlzX3NvbWUgJiYgbmV3X2EuYXNfc29tZS5AYiA9PSAiV29ybGQhIik7DQogICAgDQogICAgbGV0IG5ld19hID0gYS5teV9hY3RfYih8YnwgT3B0aW9uOjpub25lKCkpOw0KICAgIGV2YWwgYXNzZXJ0KHxffCJBc3NlcnRpb24gMiIsIG5ld19hLmlzX25vbmUpOw0KICAgIA0KICAgIHByaW50bG4oIlBhc3NlZCBhbGwgdGVzdHMuIikNCik7)

ここで、Fixにおいて`let x = *action;`と書くことは、Haskellにおいて`do`構文の中で`x <- action`とすることとほぼ同じです。

上記の`act_b`の実装は、アスタリスクとpureを除きほぼ`mod_b`と同じですので、`act_b`は「Monadicな`mod_b`」であると言えることが納得できるかと思います。

念のため、上記の`act_b`の実装が、より前に示したFunctor版の`act_b`の実装と一致することを確認しておきましょう。
Fixにおいては、Monadは以下のように定義されています。

```Rust
trait [m : *->*] m : Monad {
    bind : (a -> m b) -> m a -> m b;
    pure : a -> m a;
}
```

まず、上記の`act_b`の実装において、糖衣構文`*`を展開すると、以下のようになります。

```Rust
act_b : [m : Monad] (B -> m B) -> A -> m A;
act_b = |g, a| (
    g(a.@b).bind(|new_b|
        let new_a = a.set_b(new_b);
        pure(new_a)
    )
);
```

Monadの構造を忘却してFunctorとみなすときは、`map : (a -> b) -> m a -> m b`の定義として、`map(f) = bind(f >> pure)`すなわち`map(f) = bind(|x| let y = f(x); pure(y))`とします。
そこで、`f = |star| a.set_b(star)`とすれば、上のコードから`bind`と`pure`が消えて、`map`だけを使った実装にすることができます。

```Rust
act_b : [m : Monad] (B -> m B) -> A -> m A;
act_b = |g, a| (
    let f = |star| a.set_b(star);
    g(a.@b).map(f)
);
```

これは、Functor版の`act_b`の実装と一致しています。

よって、lens関数とは、

* フィールドに対するMonadアクションを構造体全体に延長する関数であるが、
* Functorの構造だけを使って実装できるので、`f : Functor`としたものである。

という理解をすることもできます。

# 合成可能性

構造体`A`が構造体`B`型のフィールドを持っている状況に戻りましょう。

```Rust
type A = struct { b : B };
type B = struct { v : I64 };
```

modifier関数の重要な性質は、基本的なmodifier関数を合成することで「深いmodifier関数」を作り出すことができる点にありました。

```Rust
mod_b : (B -> B) -> A -> A; // 自動定義
mod_v : (I64 -> I64) -> B -> B; // 自動定義

mod_bv : (I64 -> I64) -> (A -> A);
mod_bv = mod_b << mod_v; 
```

この「合成可能性」とも呼ぶべき性質は、Lensになっても保たれています。

```Rust
act_b : (B -> f B) -> A -> f A; // 自動定義
act_v : (I64 -> f I64) -> B -> f B; // 自動定義

act_bv : (I64 -> f I64) -> (A -> f A);
act_bv = act_b << act_v; 
```

# 「Lensはgetterとsetterのペア」との関係

「Lensはgetterとsetterのペア（と等価である）」という主張は他の解説でよく言及されているので、本当に成立しているか確認しておきましょう。
具体的には、

* 構造体`A`のフィールド`b`に対して、getter関数`@b`とsetter関数`set_b`が定義されていれば、そこから`act_b`が作れる。
* 構造体`A`のフィールド`b`に対して、lens関数`act_b`が定義されていれば、そこからgetter関数`@b`とsetter関数`set_b`が作れる。

ということを確認します。

前半の主張は、既に示した`act_b`の実装例（以下に再掲します）において、構造体を操作する関数としては`@b`と`set_b`しか使っていないことから分かります。

```Rust
act_b : [f : Functor] (B -> f B) -> A -> f A;
act_b = |g, a| (
    let new_b = g(a.@b); // `f B`型
    new_b.map(|star| a.set_b(star)) // `f A`型
);
```

lens関数からsetter関数が作れることは、直感的には明らかかもしれません。modifier関数からsetter関数を作れることは既に見ましたし、lens関数はmodifier関数の一般化であるためです。
実際、任意の型`a`に対して`f a = a`、`map(g) = g`となるようなFunctor `f`で`act_b`をインスタンス化すれば、`act_b : (B -> B) -> A -> A`となり、これはmodifier関数と全く同じ動作をします。
ただし、実際には、型システムの制約上、このような`Functor`を定義することはできません。そこで、目的のものと[自然に同型](https://en.wikipedia.org/wiki/Natural_transformation)なFunctorである`Identity`を定義して使います。同型を与える自然変換は `@data : Identity a -> a` です。

```Rust
// Identityファンクターを作る
type Identity a = struct { data : a };
impl Identity : Functor {
    map = |f, Identity { data : x }| ( Identity { data : f(x) } );
}

// `@data : Identity a -> a`の逆変換
eta : a -> Identity a;
eta = |x| Identity { data : x };

// lensからmodifierを作る
// 自動定義される`mod_b`と名前が衝突しないように`my_mod_b`とする
my_mod_b : (B -> B) -> A -> A;
my_mod_b = |g, a| (
    // `act_b`を`f = Identity`でインスタンス化すると、
    // `act_b : (B -> Identity B) -> A -> Identity A`となる。
    // これに`g`を渡すため、`eta : B -> Identity B`を合成
    let h = g >> eta;
    let id_a = a.act_b(h); // lens関数の呼び出し。結果は`Identity A`型
    id_a.@data // `@data`を使って`Identity`から取り出す
);

// modifierからsetterを作る
my_set_b : B -> A -> A;
my_set_b = |b| my_mod_b(|_| b);
```
[Playgroundで実行](https://tttmmmyyyy.github.io/fixlang-playground/?src2=bW9kdWxlIE1haW47DQppbXBvcnQgRGVidWc7DQoNCnR5cGUgQSA9IHN0cnVjdCB7IGIgOiBCIH07DQoNCi8vIElkZW50aXR544OV44Kh44Oz44Kv44K%2F44O844KS5L2c44KLDQp0eXBlIElkZW50aXR5IGEgPSBzdHJ1Y3QgeyBkYXRhIDogYSB9Ow0KaW1wbCBJZGVudGl0eSA6IEZ1bmN0b3Igew0KICAgIG1hcCA9IHxmLCBJZGVudGl0eSB7IGRhdGEgOiB4IH18ICggSWRlbnRpdHkgeyBkYXRhIDogZih4KSB9ICk7DQp9DQoNCi8vIGBAZGF0YSA6IElkZW50aXR5IGEgLT4gYWDjga7pgIblpInmj5sNCmV0YSA6IGEgLT4gSWRlbnRpdHkgYTsNCmV0YSA9IHx4fCBJZGVudGl0eSB7IGRhdGEgOiB4IH07DQoNCi8vIGxlbnPjgYvjgoltb2RpZmllcuOCkuS9nOOCiw0KLy8g6Ieq5YuV5a6a576p44GV44KM44KLYG1vZF9iYOOBqOWQjeWJjeOBjOihneeqgeOBl%2BOBquOBhOOCiOOBhuOBq2BteV9tb2RfYmDjgajjgZnjgosNCm15X21vZF9iIDogKEIgLT4gQikgLT4gQSAtPiBBOw0KbXlfbW9kX2IgPSB8ZywgYXwgKA0KICAgIC8vIGBhY3RfYmDjgpJgZiA9IElkZW50aXR5YOOBp%2BOCpOODs%2BOCueOCv%2BODs%2BOCueWMluOBmeOCi%2BOBqOOAgQ0KICAgIC8vIGBhY3RfYiA6IChCIC0%2BIElkZW50aXR5IEIpIC0%2BIEEgLT4gSWRlbnRpdHkgQWDjgajjgarjgovjgIINCiAgICAvLyDjgZPjgozjgatgZ2DjgpLmuKHjgZnjgZ%2FjgoHjgIFgZXRhIDogQiAtPiBJZGVudGl0eSBCYOOCkuWQiOaIkA0KICAgIGxldCBoID0gZyA%2BPiBldGE7DQogICAgbGV0IGlkX2EgPSBhLmFjdF9iKGgpOyAvLyBsZW5z6Zai5pWw44Gu5ZG844Gz5Ye644GX44CC57WQ5p6c44GvYElkZW50aXR5IEFg5Z6LDQogICAgaWRfYS5AZGF0YSAvLyBgQGRhdGFg44KS5L2%2F44Gj44GmYElkZW50aXR5YOOBi%2BOCieWPluOCiuWHuuOBmQ0KKTsNCg0KLy8gbW9kaWZpZXLjgYvjgolzZXR0ZXLjgpLkvZzjgosNCm15X3NldF9iIDogQiAtPiBBIC0%2BIEE7DQpteV9zZXRfYiA9IHxifCBteV9tb2RfYih8X3wgYik7DQoNCi8vIOWLleS9nOeiuuiqjeeUqOOBq%2BWei0LjgpLlrprnvqkNCnR5cGUgQiA9IFN0cmluZzsNCg0KLy8g5YuV5L2c56K66KqNDQptYWluIDogSU8gKCk7DQptYWluID0gKA0KICAgIGxldCBhID0gQSB7IGIgOiAiSGVsbG8iIH07DQogICAgbGV0IG5ld19hID0gYS5teV9zZXRfYigiV29ybGQhIik7DQogICAgZXZhbCBhc3NlcnRfZXEofF98IkFzc2VydGlvbiAxIiwgbmV3X2EuQGIsICJXb3JsZCEiKTsNCiAgICBwcmludGxuKG5ld19hLkBiKQ0KKTs%3D)

次に、lens関数からgetter関数を作る方法を考えます。

`act_b : [f : Functor] (B -> f B) -> A -> f A`を使って最後に`B`型の値が欲しいので、`f A = B`となるようなファンクター`f`で`act_b`をインスタンス化するとよさそうです。
そこで、任意の型`a`に対して`f a = B`、`map(g) = id_B`としたFunctor `f`で`act_b`をインスタンス化すると、`act_b : (B -> B) -> A -> B` となります。
この関数の動作は`act_b(g) = |a| g(a.@b)`であるため、`act_b`に恒等関数を渡すとgetter関数そのものになることがわかります。

実際には、型システムの制約上、任意の型`a`に対して`f a = B`となるようなFunctorを定義することはできません。そこで、目的のものと[自然に同型](https://en.wikipedia.org/wiki/Natural_transformation)なFunctorである`ConstantB`を定義して使います。同型を与える自然変換は `@data : ConstantB a -> B` です。

```Rust
// `ConstantB`ファンクターを作る
type ConstantB a = struct { data : B };
impl ConstantB : Functor {
    map = |f, cb| ConstantB { data : cb.@data }; // map(f)はすべて`ConstantB`上の恒等関数
}

// `@data : ConstantB a -> B`の逆変換
eta : B -> ConstantB a;
eta = |b| ( ConstantB { data : b } );

// lensからgetterを作る
my_get_b : A -> B;
my_get_b = |a| (
    // `act_b`を`f = ConstantB`でインスタンス化すると、
    // `act_b : (B -> ConstantB B) -> A -> Constant B` となる。
    // `eta`による同一視`ConstantB B = B`のもとで`id_B : B -> B`を渡したいので、
    // `eta`そのものを渡す。
    let b = a.act_b(eta); // lens関数の呼び出し。結果は`ConstantB A`型
    b.@data // `ConstantB A`から値を取り出す
);
```
[Playgroundで実行](https://tttmmmyyyy.github.io/fixlang-playground/?src2=bW9kdWxlIE1haW47DQppbXBvcnQgRGVidWc7DQoNCnR5cGUgQSA9IHN0cnVjdCB7IGIgOiBCIH07DQoNCi8vIGBDb25zdGFudEJg44OV44Kh44Oz44Kv44K%2F44O844KS5L2c44KLDQp0eXBlIENvbnN0YW50QiBhID0gc3RydWN0IHsgZGF0YSA6IEIgfTsNCmltcGwgQ29uc3RhbnRCIDogRnVuY3RvciB7DQogICAgbWFwID0gfGYsIGNifCBDb25zdGFudEIgeyBkYXRhIDogY2IuQGRhdGEgfTsgLy8gbWFwKGYp44Gv44GZ44G544GmYENvbnN0YW50QmDkuIrjga7mgZLnrYnplqLmlbANCn0NCg0KLy8gYEBkYXRhIDogQ29uc3RhbnRCIGEgLT4gQmDjga7pgIblpInmj5sNCmV0YSA6IEIgLT4gQ29uc3RhbnRCIGE7DQpldGEgPSB8YnwgKCBDb25zdGFudEIgeyBkYXRhIDogYiB9ICk7DQoNCi8vIGxlbnPjgYvjgolnZXR0ZXLjgpLkvZzjgosNCm15X2dldF9iIDogQSAtPiBCOw0KbXlfZ2V0X2IgPSB8YXwgKA0KICAgIC8vIGBhY3RfYmDjgpJgZiA9IENvbnN0YW50QmDjgafjgqTjg7Pjgrnjgr%2Fjg7PjgrnljJbjgZnjgovjgajjgIENCiAgICAvLyBgYWN0X2IgOiAoQiAtPiBDb25zdGFudEIgQikgLT4gQSAtPiBDb25zdGFudCBCYCDjgajjgarjgovjgIINCiAgICAvLyBgZXRhYOOBq%2BOCiOOCi%2BWQjOS4gOimlmBDb25zdGFudEIgQiA9IEJg44Gu44KC44Go44GnYGlkX0IgOiBCIC0%2BIEJg44KS5rih44GX44Gf44GE44Gu44Gn44CBDQogICAgLy8gYGV0YWDjgZ3jga7jgoLjga7jgpLmuKHjgZnjgIINCiAgICBsZXQgYiA9IGEuYWN0X2IoZXRhKTsgLy8gbGVuc%2BmWouaVsOOBruWRvOOBs%2BWHuuOBl%2BOAgue1kOaenOOBr2BDb25zdGFudEIgQWDlnosNCiAgICBiLkBkYXRhIC8vIGBDb25zdGFudEIgQWDjgYvjgonlgKTjgpLlj5bjgorlh7rjgZkNCik7DQoNCi8vIOWLleS9nOeiuuiqjeeUqOOBq%2BWei0LjgpLlrprnvqkNCnR5cGUgQiA9IFN0cmluZzsNCg0KLy8g5YuV5L2c56K66KqNDQptYWluIDogSU8gKCk7DQptYWluID0gKA0KICAgIGxldCBhID0gQSB7IGIgOiAiSGVsbG8iIH07DQogICAgbGV0IGIgPSBhLm15X2dldF9iOw0KICAgIGV2YWwgYXNzZXJ0X2VxKHxffCJBc3NlcnRpb24gMSIsIGIsICJIZWxsbyIpOw0KICAgIHByaW50bG4oYikNCik7)

# まとめ

* 構造体`type A = struct { b : B };`の各フィールド`b`に対して、lens関数`act_b : [f : Functor] B -> f B -> (A -> f A)`が定義される。
* これは「フィールドへの作用を構造体への作用に延長する関数」`mod_b : (B -> B) -> A -> A`のFunctor版であると考えることができる。
* 特に、`f`がMonadのときは、lens関数は「フィールドへのMonad作用を構造体へのMonad作用に延長する関数」であると考えることができる。この動作を実装するにあたってFunctorとしての構造`map`しか使わないので、`f : Functor`を要求するだけでよい。
* lens関数は合成可能である：型`B`も構造体でフィールド`v`を持つとき、フィールド`b`のフィールド`v`に対するlens関数`act_bv`は、`act_v`の後に`act_b`を合成すれば作り出すことができる。
* getter関数`A -> B`とsetter関数`B -> A -> A`からlens関数を作り出すことができる。lens関数からgetter関数とsetter関数を作り出すこともできる。
* HaskellのLensの定義`type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t`は、フィールドに作用する関数`g`が値だけではなく型すらも変えてしまう（フィールドの型が変わるので、それを含む構造体の型も変わる）場合にも対応するためのもの。

# Fixの宣伝

もしこの記事を読んで「Fixって悪くなさそうな言語だな」と思ったら、ぜひ使ってみてください。

* [リポジトリ](https://github.com/tttmmmyyyy/fixlang)
* [紹介記事](https://qiita.com/tttmmmyyyy/items/ddb1c44efd81e3fc2370)
* [他の方が書いてくださった紹介記事](https://qiita.com/pt9999/items/9bc57a735d79579a4ecc), [その方のFixライブラリのリポジトリ](https://github.com/pt9999/fixlang_minilib)