非法镜头 Haskell

unlawful lens Haskell

对于不满足属性放什么放什么的透镜状物体,有没有常见的name/type?例如像 listLength :: Lens [a] Int 这样的东西,如果你输入的长度比源列表的长度短,你会得到一个缩短的列表,但如果你输入更长的长度,原始长度将被保留。

透镜不仅仅是 forall f. Functor f => (a -> f b) -> s -> f t 类型的函数 — 它是 类型的函数,它遵守特定的法则 。特别是,(如记录 in the lens docs):

  1. 你拿回你投入的东西,
  2. 放回你得到的东西不会改变任何东西,而且
  3. 设置两次与设置一次相同

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

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


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

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