同构中前向和后向映射之间的关系(镜头包)

时间:2014-09-28 06:18:46

标签: haskell lens

s类型的同构中,为什么/不应该约束tb同构,aIso s t a b同构?

我知道我们有一个转发映射s -> a和一个向后映射b -> t,但为什么这些映射没有强加关系

 type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t)

1 个答案:

答案 0 :(得分:3)

您希望同构的不是stab,而是satb。考虑一下这个例子:

Prelude Control.Lens> (True, ()) & swapped . _1 %~ show
(True,"()")

在这里,我们正在使用Iso swapped撰写Lens _1;在此用法中,它们的组成等同于Lens _2,因此show将应用于元组(True, ())的第二个元素。请注意show是类型更改。那么我们在这里使用Iso swapped的类型是什么类型的?

  • s是我们原始元组的类型(Bool, ())
  • t是最终结果的类型(Bool, String)
  • a是交换后s的类型,((), Bool)
  • 交换之前
  • bt的类型,(String, Bool)

换句话说,我们在

类型中使用swapped
swapped :: Iso (Bool, ()) (Bool, String) ((), Bool) (String, Bool)

每个映射s -> ab -> t都是双射,但其他类型之间没有必要的关系。

至于为什么似乎没有Iso所列出的法律规定这些法律必须是双性恋,我不知道。

编辑:部分"为什么它是镜头系列"在@bennofs在上面的评论中发布的链接确实为我澄清了一些事情。显然,爱德华·凯梅特希望这些类型完全自由地变化。

虽然在光学类型中无法直接表达而不会使其难以使用, 目的是改变类型的光学系列(LensIso或其他)应具有类型系列innerouter给出的类型。如果Iso的其中一种类型是

anIso :: Iso s t a b

然后应该有两种索引类型ij,以便

s = outer i
t = outer j
a = inner i
b = inner j

此外,您可以交换ij,虽然没有自动执行此操作,但结果 仍然是您的多态的合法类型Iso。即您还应该被允许使用

类型的anIso
anIso :: Iso t s b a

显然这适用于swapped。这两种都是合法的类型:

swapped :: Iso (Bool, ()) (Bool, String) ((), Bool) (String, Bool)
swapped :: Iso (Bool, String) (Bool, ()) (String, Bool) ((), Bool)

换句话说,如果多态Iso系列的类型发生了变化,那么还需要支持反向类型更改。 (也是组合类型的变化。我从类别理论中嗅到了一种自然的转变,我怀疑这也是Kmett对此的一种看法。)

另请注意,如果您将多态Iso构造为

f :: s -> a
g :: b -> t
iso f g :: Iso s t a b

然后,为了使此 具有iso f g :: Iso t s a b类型,我们需要fg才能拥有类型

f :: t -> b
g :: a -> s

请注意,在其第一个类型f中使用的s -> a具有与其第二个类型g中使用的a -> s相反的正确类型,并且相应地以相反的方式

对于一个具体的例子,swapped在这里有点不好,因为用于元组的fg是相同的,基本上它们都是\(x,y) -> (y,x),这是它自己的逆。我在Simple中看到的最好的其他非Control.Lens.Iso示例是curried,这似乎有点过于复杂而无法澄清。