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

sev*_*evo 0 haskell fold haskell-lens

根据Control.Foldl文档:

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

type Handler a b 
   = forall x. (b -> Constant (Endo x) b) -> a -> Constant (Endo x) a
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*zer 5

你的方向已经完全混淆了.这里描述的光学器件都是形式

 type Foo s t a b = forall f. SomeConstraints f => (a -> f b)-> (s -> f t)
Run Code Online (Sandbox Code Playgroud)

对于棱镜而言,它应该与任意的Choice探测器配合使用,但它->是这种结构的典型示例,因此我们可以专门研究棱镜,以便只在这些探测器上工作.这个过程合法的原因与我们将要做的事情完全相同,f因此暂停一分钟的怀疑并阅读

现在,如果我们实例s,并taabb,然后我们得到

 forall f. SomeConstraints f => (b -> f b) -> (a -> f a)
Run Code Online (Sandbox Code Playgroud)

现在这意味着如果我们有一些光学元件,如透镜,棱镜或遍历,我们可以实例化它的类型参数,使它几乎以a的形式Handler.唯一的区别是我们保证f可以满足任何条件,只要它满足我们选择的约束.如果我们知道Constant (Endo x)满足这些约束条件,那么我们就可以默默地专门研究光学元件只能用它f来工作.这只是简单的多态实例化!因为它Constant a是一个FunctorApplicative它将适用于任何镜头或遍历.这种隐式的子类型和实例化是使透镜包工作的核心,通过将所有这些事物保持透明Haskell让我们混合和匹配抽象,它将自动地定位于我们所用的任何光学系统的"最大下界"使用.

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