非法镜头 Haskell

Posted

技术标签:

【中文标题】非法镜头 Haskell【英文标题】:unlawful lens Haskell 【发布时间】:2021-03-30 05:52:54 【问题描述】:

对于不满足取出您放入的物品的属性的类似镜头的物体,是否有一个通用名称/类型?例如像 listLength :: Lens [a] Int 这样的东西,如果你输入的长度比源列表的长度短,你会得到一个缩短的列表,但如果你输入的长度更长,原始长度会被保留。

【问题讨论】:

你能想出你希望这样一个对象具有的属性吗?例如。如果你把你拿出的东西放进去,你什么都没有改变? @luqui 我只是想知道是否有任何记录的概念包含我的示例非法镜头。 您所说的与partsOf 非常相似,只要保持某些不变量,它就会将遍历变成镜头。您可以在该函数的文档中看到注释,但他们实际上并没有命名这个想法。 【参考方案1】:

镜头不仅仅是forall f. Functor f => (a -> f b) -> s -> f t 类型的函数——它是一个符合特定规律的函数。特别是(如记录的in the lens docs):

    你会取回你投入的东西, 收回你所得到的并不会改变任何事情,并且 设置两次与设置一次相同。

如果你的函数不遵守这些规律,那么它只是一个类型类似于镜头的函数。

在您的特定示例中,listLength 违反了第一和第三定律,因此它不是镜头。也就是说,它可以作为 Getter 正常工作,我认为这是我们可以说的唯一原则。


更一般地说,询问那些缺乏规律的事物是没有意义的,因为事物往往是由它们遵守的法律而非不遵守的法律来定义的。例如,我指出listLength 是一个非常好的Getter,因为它始终从[a] 输入中提取一个值。

那么,我会问你:它与总是发出 0 的函数 listZero :: Lens [a] Int 有什么区别?你能想出一个listLength 遵守listZero 不遵守的一般规律吗?如果是这样,那么您可以在当前文献中实际寻找一些东西:也就是说,listLength 是一组遵守某些(可能很有趣)定律的函数之一。如果不是,那么您只有一个类型的函数,使它看起来像一个镜头。

【讨论】:

listLength 遵循标准的往返半定律,而 listZero 可能不会,这取决于它对“放置”方向的实现。有问题的法律是这样的:如果put v x = v',那么put v' (get v') = v'。在一些较早的文献中,遵守两个往返半定律就足以称一个事物为镜头。表现良好的镜片也服从您的(1)和(2);现在可以从lens 包中获得的符合您所有三个定律的东西被称为行为良好的镜头。

以上是关于非法镜头 Haskell的主要内容,如果未能解决你的问题,请参考以下文章

有关镜头F值

相机镜头参数怎么看

光学镜头与模组

尼康D型镜头手动对焦应该如何操作?

尼康D型镜头手动对焦应该如何操作?

进阶篇--相机镜头