Lenses似乎没有任何缺点,但与标准Haskell相比具有显著优势:**是否有任何理由我不应该在任何可能的地方使用镜头?**是否有性能考虑?另外,模板Haskell是否有任何显著的开销?
zi8p0yeb1#
透镜是在数据构造函数上使用直接闭包的一种替代方法,因此透镜与直接使用函数和数据构造函数具有大致相同的警告。一些缺点,因为这:
A { B { C { bla = "foo" } } }
......和Lens A String类型的透镜,每次“修改”该镜头时,您将创建新的A、B和C。这在Haskell(创建大量对象)中并不罕见,但对象创建隐藏在镜头后面,因此很难发现它是潜在的性能下降点。
Lens A String
A
B
C
优点:
data-lens-fd
focus
withSomething
然而,透镜并不总是与数据构造函数上的闭包同构,下面是一些不同之处(这里以data-lens作为实现):
data-lens
Store
模板Haskell代码在编译时运行,无论如何不会影响镜头的运行时性能。
gev0vcfq2#
我假设使用 data-lens 包。Lenses在处理类似数据的东西(记录、元组、Map等)时表现非常好。事实上,它们有时甚至比普通方法表现得更好,可能是因为更好的共享。在性能方面,它产生的性能与手工编写的代码大致相同。然而,也有一些功能性的东西,镜头可能会有一个惩罚。例如,我记得至少有一次使用这样的镜头:
result :: (Eq a) => a -> Lens (a -> b) b
虽然查询非常快,但我偶尔会覆盖函数的某些结果值,以根据特定场景调整它,这相当于将函数体封装在一个大的if中。当然,性能影响与镜头本身无关,但这是值得注意的。
if
2条答案
按热度按时间zi8p0yeb1#
透镜是在数据构造函数上使用直接闭包的一种替代方法,因此透镜与直接使用函数和数据构造函数具有大致相同的警告。
一些缺点,因为这:
......和
Lens A String
类型的透镜,每次“修改”该镜头时,您将创建新的A
、B
和C
。这在Haskell(创建大量对象)中并不罕见,但对象创建隐藏在镜头后面,因此很难发现它是潜在的性能下降点。优点:
data-lens-fd
的例子),由于广泛的数据共享,这使得在大多数时候 * 避免 * 重新创建大量对象成为可能。参见focus
函数的例子,以及在Snap Web框架中使用withSomething
函数的类似模式。然而,透镜并不总是与数据构造函数上的闭包同构,下面是一些不同之处(这里以
data-lens
作为实现):data-lens
,它是Store
comonad。这意味着每次你创建一个镜头,都会有一个非常小的额外开销,因为要创建的数据结构。模板Haskell代码在编译时运行,无论如何不会影响镜头的运行时性能。
gev0vcfq2#
我假设使用 data-lens 包。Lenses在处理类似数据的东西(记录、元组、Map等)时表现非常好。事实上,它们有时甚至比普通方法表现得更好,可能是因为更好的共享。在性能方面,它产生的性能与手工编写的代码大致相同。
然而,也有一些功能性的东西,镜头可能会有一个惩罚。例如,我记得至少有一次使用这样的镜头:
虽然查询非常快,但我偶尔会覆盖函数的某些结果值,以根据特定场景调整它,这相当于将函数体封装在一个大的
if
中。当然,性能影响与镜头本身无关,但这是值得注意的。