问题描述
似乎没有任何缺点,同时比标准的Haskell有明显的优势:有没有我不应该在任何可能的情况下使用镜片?是否有性能方面的考虑?另外,模板Haskell是否有明显的开销?透镜构成了使用数据构造函数的直接闭包的替代方法。因此镜头与使用函数和数据构造函数直接相同的警告。
一些缺点是因为这个原因:
每当您修改镜头时,您可能会导致(重新)创建大量对象。例如,如果你有这样的数据结构:
A {B {C {bla =foo}}}
...以及类型 Lens A String
,你将创建一个新的 A
, B
和 C
每次你修改该镜头。这在Haskell中并不罕见(创建大量对象),但创建对象隐藏在镜头后面,难以发现潜在的性能下降。
以及优点:$ b
$ b
- 透镜与普通记录结合可以很好地用于(参见函数,以及在Snap Web框架中使用
withSomething
函数的类似模式。 - 镜头显然实际上并没有实际修改任何内存,所以当您需要在并发上下文中推理状态时,镜头非常有用。因此,镜片在处理各种图形时非常有用。然而,透镜并不总是与数据构造器上的闭合同构。以下是一些差异(采用作为这里的实现):
- 大多数透镜实现使用某种形式的数据类型来将访问器和增变器作为一对。对于
data-lens
,这是。这意味着每次创建镜头时,由于正在创建数据结构,因此会产生非常小的额外开销。 - 因为镜头依赖于某些未知映射的值,所以它可能会变得更难理解垃圾收集,并且你可能会(逻辑)内存泄漏,因为你忘记了你正在使用一个非常通用的镜头,这取决于一大块内存。举个例子,一个镜头访问某个大型矢量中的一个元素,该镜头由另一个隐藏第一个镜头的镜头组成,这使得难以看出组合镜头依然依赖于大量内存。 >
模板Haskell代码在编译时运行,不会影响透镜的运行时性能。
Lenses don't seem to have any disadvantages while having significant advantages over standard Haskell: Is there any reason I shouldn't use lenses wherever possible? Are there performance considerations? Additionally, does template Haskell have any significant overhead?
解决方案Lenses form an alternative to using direct closures over data constructors. Lenses therefore have approximately the same caveats as using functions and data constructors directly.
Some of the cons because of this:
Every time you modify a lens, you might potentially cause a lot of objects to be (re)created. For example, if you have this data structure:
A { B { C { bla = "foo" } } }
...and the lens of type
Lens A String
, you will create a newA
,B
andC
every time you "modify" that lens. This is nothing unusual in Haskell (creating lots of objects), but the object creation is hidden behind the lens, making it hard to spot as a potential performance sink.- A lens could also create inefficiencies due to the "mapping function" being used. For example, if you make a lens that modifies the 26 element in a list, it might cause a lot of slowdowns due to the lookup time.
And the pros:
- Lenses, in combination with normal records, can be used beautifully with the state monads (see
data-lens-fd
for an example), and this makes it possible to avoid recreating a lot of objects most of the time, due to extensive data sharing. See for example thefocus
function, and a similar pattern of usingwithSomething
functions in the Snap Web framework. - Lenses obviously don't actually modify any memory in-place, so they are very useful when you need to reason about state in the context of concurrency. Lenses would therefore be very useful when dealing with graphs of various kinds.
Lenses are not always isomorphic to closures over data constructors, however. Here are some of the differences (taking
data-lens
as the implementation here):- Most lens implementations use some form of data type to store the "accessor" and "mutator" as a pair. For
data-lens
, it's theStore
comonad. This means that every time you create a lens, there'll be a very small extra overhead due to that data structure being created. - Because lenses depend on values via some unknown mapping, it might become harder to reason about garbage collection, and you might get (logical) memory leaks because you forgot that you are using a very generic lens that depends on some large chunk of memory. Take, for example, a lens that accesses an element in some large vector, which is composed with another lens that thus hides the first lens, making it difficult to see that the composed lens still depends on the large amount of memory.
Template Haskell code runs at compile time, and does not affect the runtime performance of lenses whatsoever.
这篇关于使用镜头有什么优点和缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- 大多数透镜实现使用某种形式的数据类型来将访问器和增变器作为一对。对于