为什么我们需要Control.Lens.Reified?有什么理由我不能Lens
直接放入容器吗?reify
无论如何,意味着什么?
dfe*_*uer 12
我们需要具体化的镜头,因为Haskell的类型系统具有预测性.我不知道究竟是什么意思的技术细节,但它禁止类似的类型
[Lens s t a b]
Run Code Online (Sandbox Code Playgroud)
出于某些目的,使用它是可以接受的
Functor f => [(a -> f b) -> s -> f t]
Run Code Online (Sandbox Code Playgroud)
相反,但是当你达到那个目的时,你就得不到了Lens
; 你得到一个LensLike
专门的一些仿函数或另一个.该ReifiedBlah
newtypes让你挂在充分多态性.
在操作上,[ReifiedLens s t a b]
是一个函数列表,每个函数都接受一个Functor f
字典,而forall f . Functor f => [LensLike f s t a b]
一个函数接收Functor f
字典并返回一个列表.
至于什么"reify"意味着,好的,字典会说些什么,而这似乎在Haskell中转化为一种相当令人惊叹的特定含义.所以没有评论.
问题是,在Haskell中,类型抽象和应用程序是完全隐含的; 编译器应该在需要的地方插入它们.设计"impredicative"扩展的各种尝试都失败了,编译器会巧妙地猜测在哪里放置它们.所以最安全的事情最终依赖于Haskell 98规则:
所以,如果我定义一个简单的镜头:[1]
lensHead f [] = pure []
lensHead f (x:xn) = (:xn) <$> f x
Run Code Online (Sandbox Code Playgroud)
并在表达式中使用它:
[lensHead]
Run Code Online (Sandbox Code Playgroud)
lensHead
被自动地应用到一些组类型参数; 在这一点上,它不再是一个镜头,因为它在仿函数中不再是多态的.外卖是:表达总是有一些单形类型; 所以它不是镜头.(你会注意到这些lens
函数采用了类型的参数,Getter
并且Setter
它们是单态类型,出于类似的原因.但是a [Getter s a]
不是透镜列表,因为它们只专门用于吸气剂.)
什么reify
意思?字典定义是'make real'.哲学中使用"具体化"来指代将事物视为真实(而不是理想或抽象)的行为.在编程中,它倾向于将某些通常不能被视为数据结构并将其表示为一个的东西.例如,在非常古老的Lisps中,没有使用成为一流的函数; 相反,你必须使用S-Expressions传递'函数',eval
当你需要调用函数时它们.S-Expressions以您可以在程序中操作的方式表示函数,这被称为具体化.
在Haskell中,我们通常不需要像Lisp S-Expressions这样精细的具体化策略,部分原因是该语言旨在避免需要它们; 但是由于
newtype ReifiedLens s t a b = ReifiedLens (Lens s t a b)
Run Code Online (Sandbox Code Playgroud)
具有相同的效果,即获取多态值并将其转换为真正的第一类值,它被称为具体化.
如果表达式总是具有单形类型,为什么这样做?好吧,因为Rank2Types扩展添加了第三条规则:
ReifiedLens
是这样的秩-2功能; 所以当你说
ReifiedLens l
Run Code Online (Sandbox Code Playgroud)
你得到一个围绕参数的类型lambda ReifiedLens
,然后l
立即应用于lambda绑定类型参数.所以l
实际上只是eta扩展.(编译器可以自由地减少这个并直接使用l
).
然后,当你说
f (ReifiedLens l) = ...
Run Code Online (Sandbox Code Playgroud)
在右侧,l
是一个具有多态类型的变量,因此每次使用l
都会立即隐式分配给表达式进行类型检查所需的任何类型参数.所以一切都按照你期望的方式运作.
另一种思考方式是,如果你说的话
newtype ReifiedLens s t a b = ReifiedLens { unReify :: Lens s t a b }
Run Code Online (Sandbox Code Playgroud)
两个函数ReifiedLens
和unReify
像显式的类型的抽象和应用运营商行为; 这允许编译器确定您希望抽象和应用程序发生的位置,以至于不会出现具有impredicative类型系统的问题.
[1]在lens
术语中,这显然被称为"镜头"以外的东西; 我对镜片的全部了解都来自SPJ对它们的介绍,所以我无法对其进行验证.重点仍然存在,因为多态性仍然是必要的,以使其作为getter和setter工作.