我对信号光学系统不屑一顾,但我遇到了一些我无法弄清楚的问题。
Lens的profunctor编码及其反转如下:
type Optic p s t a b = p a b -> p s t
type Lens s t a b = forall p. Strong p => Optic p s t a b
type LensyReview t b = forall p. Costrong p => Optic p t t b b
您可以使用
在它们之间自由地来回转换newtype Re p s t a b = Re { unRe :: p b a -> p t s }
instance Profunctor p => Profunctor (Re p s t) where
dimap f g (Re p) = Re (p . dimap g f)
instance Strong p => Costrong (Re p s t) where
unfirst (Re p) = Re (p . first')
unsecond (Re p) = Re (p . second')
instance Costrong p => Strong (Re p s t) where
first' (Re p) = Re (p . unfirst)
second' (Re p) = Re (p . unsecond)
re :: Optic (Re p a b) s t a b -> Optic p b a t s
re optic = unRe (optic (Re id)))
现在,我尝试为profunctor镜头实现选择功能(https://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Lens.html#v:choosing)。
事实证明,这需要附加的类型类:
class Profunctor p => SumProfunctor p where
(+++!) :: p a b -> p a' b' -> p (Either a a') (Either b b')
然后,如果我们在Lens中包含SumProfunctor,我们可以编写
choosing :: Lens s t a b -> Lens s' t' a b -> Lens (Either s s') (Either t t') a b
choosing optic optic' = \pab -> optic pab +++! optic' pab
但是然后需要遵循Re的模式的另一个“双重”类型类,
instance Unknown p => ProfunctorSum (Re p s t)
instance ProfunctorSum p => Unknown (Re p s t)
以便镜头是可逆的。
我想出的最接近的是:
class Profunctor p => Unknown p where
unsum :: p (Either a a') (Either b b') -> (p a b -> r) -> (p a' b' -> r) -> r
因为其中有一个Tagged的明智实例,然后您可以编写
instance Unknown p => SumProfunctor (Re p s t) where
Re f +++! Re g = Re (\s -> unsum s f g)
但在另一个方向上进行定义,即
instance SumProfunctor p => Unknown (Re p s t) where
unsum = ???
似乎不可能。
在正确的轨道上还是需要其他方法?
答案 0 :(得分:1)