为什么所有镜头都与Foldl.Handler类型匹配?

时间:2016-03-21 19:34:17

标签: haskell fold lens

根据Control.Foldl documentation

  

任何镜头,遍历或棱镜都会作为处理程序进行打字检查

type Handler a b 
   = forall x. (b -> Constant (Endo x) b) -> a -> Constant (Endo x) a

有人可能声称,因为镜头允许任何Functor不是Constant镜片的唯一子集应进行类型检查。为什么这个陈述不正确?

1 个答案:

答案 0 :(得分:5)

你的指示混乱了。这里描述的光学器件都是

形式
 type Foo s t a b = forall f. SomeConstraints f => (a -> f b)-> (s -> f t)

对于棱镜而言,它应该与任意Choice运算符一起工作,但->是这种结构的典型例子,所以我们可以专门研究棱镜只适用于这些影响者。这个过程合法的原因与我们对f的处理方式相同,因此暂停一分钟的怀疑并阅读

现在,如果我们将st实例化为a,将ab实例化为b,那么我们就会

 forall f. SomeConstraints f => (b -> f b) -> (a -> f a)

现在这意味着如果我们有一些光学器件,如透镜,棱镜或遍历,我们可以实例化其类型参数,使其几乎以Handler的形式存在。唯一的区别是我们保证适用于任何f,只要它满足我们选择的约束。如果我们知道Constant (Endo x)满足这些约束条件,那么我们可以默默地将该光学元件专门用于仅使用f 。这只是简单的多态实例化!由于Constant aFunctorApplicative,因此它适用于任何镜头或遍历。这种隐含的子类型和实例化是使镜头包工作的核心,通过将所有这些事物保持透明,Haskell让我们混合和匹配抽象,它将自动落在最大的下限上#34 ;无论我们使用什么样的光学器件。

整个事情归结为这样的事实:在Haskell中,如果我们有e :: forall t. T,那么对于任何适当的k tau我们也有e :: [tau/t]T。一旦我们抛出类型约束,就会有一些皱纹,但总的来说,所有这些都只是默认情况下Haskell中类型应用程序是静默的。