在s
类型的同构中,为什么/不应该约束t
与b
同构,a
与Iso 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)
答案 0 :(得分:3)
您希望同构的不是s
到t
或a
到b
,而是s
到a
和t
到b
。考虑一下这个例子:
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)
b
是t
的类型,(String, Bool)
换句话说,我们在
类型中使用swapped
swapped :: Iso (Bool, ()) (Bool, String) ((), Bool) (String, Bool)
每个映射s -> a
和b -> t
都是双射,但其他类型之间没有必要的关系。
至于为什么似乎没有Iso
所列出的法律规定这些法律必须是双性恋,我不知道。
编辑:部分"为什么它是镜头系列"在@bennofs在上面的评论中发布的链接确实为我澄清了一些事情。显然,爱德华·凯梅特不希望这些类型完全自由地变化。
虽然在光学类型中无法直接表达而不会使其难以使用,
目的是改变类型的光学系列(Lens
,Iso
或其他)应具有类型系列inner
和outer
给出的类型。如果Iso
的其中一种类型是
anIso :: Iso s t a b
然后应该有两种索引类型i
和j
,以便
s = outer i
t = outer j
a = inner i
b = inner j
此外,您可以交换i
和j
,虽然没有自动执行此操作,但结果 仍然是您的多态的合法类型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
类型,我们需要f
和g
才能拥有类型
f :: t -> b
g :: a -> s
请注意,在其第一个类型f
中使用的s -> a
具有与其第二个类型g
中使用的a -> s
相反的正确类型,并且相应地以相反的方式
对于一个具体的例子,swapped
在这里有点不好,因为用于元组的f
和g
是相同的,基本上它们都是\(x,y) -> (y,x)
,这是它自己的逆。我在Simple
中看到的最好的其他非Control.Lens.Iso
示例是curried
,这似乎有点过于复杂而无法澄清。