非法镜头哈斯克尔
是否有一个类似镜头的物体的通用名称/类型不满足取出你放入的东西的特性?例如listLength :: Lens [a] Int,如果您输入的长度比源列表的长度短,则会得到一个缩短的列表,但是如果您输入的长度更长,则原始长度将被保留。
回答
镜头不仅仅是具有该类型的函数forall f. Functor f => (a -> f b) -> s -> f t - 它是具有该类型的函数,该函数遵循某些定律。特别是(如镜头文档中所述):
- 你拿回你投入的东西,
- 放回你得到的东西不会改变任何东西,而且
- 设置两次与设置一次相同。
如果您的函数不遵守这些定律,那么它只是一个类型类似于镜头的函数。
在您的特定示例中,listLength违反了第一定律和第三定律,因此它不是镜头。也就是说,它作为Getter.
更一般地说,询问缺乏规律的事物并没有什么意义,因为事物往往由它们遵守的法律而不是它们不遵守的法律来定义。例如,我指出这listLength使得 a 非常好,Getter因为它始终如一地从[a]输入中提取一个值。
那么,我会问你:它与listZero :: Lens [a] Int总是发出的函数有什么区别0?你能想出一个不listLength遵守的一般规律listZero吗?如果是这样,那么您实际上可以在当前文献中寻找一些东西:也就是说,它listLength是遵守某些(可能有趣的)定律的一组函数之一。如果不是,那么您只有一个类型使其看起来像镜头的函数。
- `listLength` obeys a standard-ish round-trip-and-a-half law, while `listZero` may not, depending on its implementation of the "put" direction. The law in question is this: if `put v x = v'`, then `put v' (get v') = v'`. In some older literature, obeying two round-trip-and-a-half laws was enough to call a thing a lens; well-behaved lenses also obeyed your (1) and (2); and the things now available from the `lens` package that obey all three of your laws were called very well-behaved lenses.