ice*_*man 2 haskell record haskell-lens
我正在阅读有关镜头的教程,在介绍中,作者lens通过展示我们如何使用标准Haskell实现OOP风格的"setter"/"getter"的一些示例来激发这一概念.我对以下示例感到困惑.
假设我们User根据图1(下面)定义代数数据类型.本教程(正确地)指出我们可以通过NaiveLens数据类型和nameLens函数实现"setter" 功能(也在图1中).图2给出了一个示例用法.
我很困惑为什么我们需要这样一个精心设计的构造(即NaiveLens数据类型和nameLens函数)来实现"setter"功能,当下面的(有点明显的)函数似乎同样很好地完成工作时:set' a s = s {name = a}.
但是,鉴于我的"显而易见"功能正是lambda函数的一部分nameLens,我怀疑使用下面的结构确实有一个优势,但我太密集了,看不出那个优点是什么.我希望其中一个Haskell向导可以帮助我理解.
图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})
Run Code Online (Sandbox Code Playgroud)
图2(示例用法):
?: let john = User {name="John",age=30}
john :: User
?: set nameLens "Bob" john
User {name = "Bob", age = 30}
it :: User
Run Code Online (Sandbox Code Playgroud)