私はレンズに関するチュートリアルを読んでいます。導入部で、著者は、lens
標準の Haskell を使用して OOP スタイルの「セッター」/「ゲッター」を実装する方法のいくつかの例を示して、コンセプトの動機付けをしています。次の例で混乱しています。
User
図 1 (下記) のように代数データ型を定義するとしましょう。NaiveLens
チュートリアルでは、データ型と関数を使用して "セッター" 機能を実装できると (正しく) 述べていnameLens
ます (図 1 も参照)。使用例を図 2 に示します。
次の(やや明白な)関数が同じようにうまく機能するように見えるのに、なぜ「セッター」機能を実装するためにそのような精巧な構造(つまり、NaiveLens
データ型と関数)が必要なのか、私は困惑しています。 nameLens
set' a s = s {name = a}
ただし、私の「明白な」関数が の一部であるラムダ関数に他ならないことを考えると、nameLens
以下の構成を使用することには確かに利点があると思いますが、密度が高すぎてその利点が何であるかを確認できません。Haskell ウィザードの 1 人が理解を助けてくれることを願っています。
図 1 (定義):
data User = User { name :: String
, age :: Int
} deriving Show
data NaiveLens s a = NaiveLens { view :: s -> a
, set :: a -> s -> s
}
nameLens :: NaiveLens User String
nameLens = NaiveLens name (\a s -> s {name = a})
図 2 (使用例):
λ: let john = User {name="John",age=30}
john :: User
λ: set nameLens "Bob" john
User {name = "Bob", age = 30}
it :: User