Sib*_*ibi 4 haskell haskell-lens
我一直在阅读这篇文章,并在其中一节中说明:
镜头倒退.我们不能使
(.)行为像函数一样吗?你是对的,我们可以.我们不是出于各种原因,但直觉是正确的.镜片应该像功能一样组合.有一点重要的是id可以在任何镜头前后组合而不影响它.
这是什么意思由镜头构成倒退?
这也意味着什么:我们不能使(.)行为像函数一样吗?
(.)是一个函数,通过使用它与镜头,它(.)表现得像其他东西?
该Lens类型:
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
Run Code Online (Sandbox Code Playgroud)
为了说明的目的,我们可以坚持不那么普通的简单镜头类型,Lens'.然后右侧变为:
forall f. Functor f => (a -> f a) -> s -> f s
Run Code Online (Sandbox Code Playgroud)
直观地,(a -> f a)是对类型结构的一部分的操作s,其被促进对整个结构的操作,(s -> f s).(仿函数类型构造函数f是技巧的一部分,它允许镜头推广getter,setter和许多其他东西.我们现在不需要担心它.)换句话说:
(请注意,在我刚才的描述中,"part"和"whole"出现在不同的顺序中.)
现在,镜头是一个功能,可以组成功能.我们知道,(.)有类型:
(.) :: (y -> z) -> (x -> y) -> (x -> z)
Run Code Online (Sandbox Code Playgroud)
让我们让所涉及的类型简单的镜头(为了清楚起见,我将放弃约束和forall).x成为a -> f a,y成为s -> f s,z成为t -> f t.(.)那么专门的类型是:
((s -> f s) -> t -> f t) -> ((a -> f a) -> s -> f s) -> ((a -> f a) -> t -> f t)
Run Code Online (Sandbox Code Playgroud)
我们得到的镜头有类型(a -> f a) -> (t -> f t).因此,合成镜头firstLens . secondLens对所关注的部分进行操作,secondLens并使其在整个结构上进行操作firstLens.这恰好与组成OO样式字段引用的顺序相匹配,这与组成vanilla Haskell记录访问器的顺序相反.
您可以将Getter镜头的一部分视为函数,可以使用 提取该函数view。例如,lens函数的写法fst是:
view _1 :: (a,b) -> a
Run Code Online (Sandbox Code Playgroud)
现在观察:
view _1 . view _2 :: (c, (a,b)) -> a -- First take the second pair element, then the first
view (_1 . _2) :: ((b,a) ,c) -> a -- This is "backwards" (exactly the opposite order of the above)
Run Code Online (Sandbox Code Playgroud)
对于镜头来说,(.)其行为与功能不同。对于函数,f . g意味着“首先应用 g,然后应用 f”,但对于镜头,意味着first use the lens f, then use the lens g。实际上,(.)两种类型的功能是相同的,但镜头的类型使其看起来像是倒退的。
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |