Optics
Opticsの中に以下が含まれる
Setter
Getter
Fold
普通のgetter/setterは対象が1つだが、それを0個以上の任意の数を対象にできる
setter側
set
単一の値を取り、複数の対象全てに対して更新する
例えばtreeを対象にすると、全leafがその値になる感じ
over/modify
引数が関数版
getter側
view/get
対象は1つ
preview/getOptional
対象は0または1
optionalなやつにも使えるということ
配列のindexが範囲外になる可能性のあるやつとか
reduce/traverse/toList/toArray
対象は無制限
上記の6パターン(setが2つ * getが3つ)ともう1パターンの合計7つのopticsがある
table:optics
対象が1つ 対象が0または1つ 対象は任意の数 アクセスなし
これらは互いに組み合わせることができる
値を生成するBuilders
table:optics
対象が1つ 対象が0または1つ 対象は任意の数 アクセスなし
IsoとPrismを両方知らないせいで全く意味がわからないmrsekut.icon
https://gyazo.com/2a4ee4ba425a5f09c9e261453b34acab https://xebia.com/blog/a-very-short-intro-to-optics/
code:hs
type Optic p f s t a b = p a (f b) -> p s (f t)
抽象的過ぎすぎて意味わからんwmrsekut.icon
LensとPrismの一般化であり、特定のパートへのアクセスを表現する方法として最も強力です。Opticは「view」、「update」、「over」(特定の関数を適用)など、より多くの操作を提供します。
型シノニムは非常に一般的で、pとfは具体的な操作(たとえばLensやPrism)を表すためにさまざまな型約束(たとえばFunctorやApplicative)とともに特殊化されます。gpt-4.icon
データ構造の一部に対するgetterとsetterを提供する
code:hs
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
code:hs
type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
Lensとは逆で、可能性として存在する一部分への「フォーカス」を提供します。具体的には、データ構造が特定のバリアント(Haskellでのデータ型の一つのコンストラクタ)である場合にのみアクセス可能な部分に焦点を当てます。
Prismは一般に可能性として存在する値に対して働きます。その値が存在する場合はそれを取り出し、存在しない場合は何もしません。また、元のデータ構造を新しいバリアントで置き換えることもできます。gpt-4.icon
Setter
Getter
Fold
composableである
immutableである
学ぶ順序 by gpt-4.icon
Opticsの各要素は異なる種類のデータ操作を抽象化していますが、これらは互いに関連していて一部の要素は他の要素の特殊ケースとなっています。したがって、学習する際には以下の順序で進むことをお勧めします。
1. **Optics**:まず最初にOpticsの全体的な概念を理解します。これにより、どのようにして複雑なデータ操作を抽象化し、一貫したインターフェースで行うかの概観を持つことができます。
まあこれはざっくり概要を掴め、ってぐらいだろうねmrsekut.icon
2. **GetterとSetter**:GetterとSetterは、レコードフィールドの読み取りと書き込みを抽象化したもので、最も基本的な操作となります。これらを理解することで、Opticsの基本的な働きを把握することができます。
3. **Lens**:LensはGetterとSetterを一つに組み合わせたもので、データの一部に対する読み書きを可能にします。これはOpticsの中心的な要素であり、他の多くの要素(PrismやTraversalなど)の基盤となります。
4. **Fold**:Foldは複数の値を抽出する操作を抽象化します。これは読み取り専用の操作で、Traversalの一部とも考えることができます。
5. **Traversal**:TraversalはLensを一般化したもので、データ構造内の複数の位置に対する読み書きを可能にします。Traversalの理解には、LensとFoldの理解が必要となります。
6. **Prism**:Prismは、選択的なデータ操作を抽象化します。つまり、ある型の値が特定のサブタイプまたは状態を持つ場合にのみ操作を適用します。これはLensとTraversalの一部とも考えることができます。
7. **Review**:ReviewはPrismの一部で、ある型から別の型への「逆」の操作を提供します。
8. **Iso**:Isoは値の完全な変換を抽象化し、LensやPrismの特殊ケースとなります。
9. **Affine TraversalとAffine Fold**:これらはTraversalとFoldの特殊ケースで、高々一つの要素に対する操作を抽象化します。
この順序で学ぶことで、各要素が他の要素とどのように関連し、一般化や特殊化の関係にあるのかを理解することが容易になります。各ステップで、具体的な例と実際のHaskellのコードを通じて概念を理解することをお勧めします。
概要をパット思い出せるようなコード片など
各概念の関係性
各概念の名前の意味
由来でも良いし、ニュアンスでも良いので、とにかくイメージしてコンセプトを頭に思い浮かべるのに使いたいmrsekut.icon
学ぶ順序
トップダウンにやるべきか、ボトムアップにチュートリアルをこなすべきか
なぜ必要になるのか。ないとどう不便なのか
また、その嬉しさはHaskell固有のものなのか
例えば、それをTypeScriptなどに応用できるものなのか
各言語での実装
Haskell
Scara
Monocle
TypeScript
Kotlin
Swift
F#
PureScript
Elm
似たようなものにFoucsというのもあるらしい
ほんまかどうかしらんが gpt-4.iconによると
"Optics" という用語は "Lens", "Prism", "Traversal" などを包含する概念の一般化として使われます。しかし、Haskellのライブラリとしては "lens" という名前がつけられています。なぜなら、"lens" という用語が最初に導入され、その他の概念 ("Prism", "Traversal" など) はそれ以降に追加されてきたからです。
一般に、"lens" ライブラリは "optics" を扱うためのライブラリとして広く認識されています。したがって、"lens" ライブラリを指して "optics" ライブラリと言うことも多いです。
ただし、あくまでライブラリの名前が "lens" であるだけで、それが "Lens" の概念だけを含むわけではないということを理解していれば混乱は避けられるでしょう。
線形型版もある
Opticの概要の記事
他のOpticsより理解しやすい?
様々なencodingがある