Control.Lens.Iso
包含许多很棒的函数,用于将Iso
提升为有用抽象的各种类型参数。例如:
mapping
s ,Functor
{li> contramapping
Contravariant
仿函数dimapping
,lmapping
和rmapping
Profunctor
s
{li> bimapping
Bifunctor
s
我正在寻找将Iso
提升到first
的{{1}}参数的功能,但它似乎并不存在。我现在正在定义它:
Bifunctor
这个功能在某个地方是否已经存在,或者firsting
:: Bifunctor f
=> AnIso s t a b
-> Iso (f s x) (f t y) (f a x) (f b y)
firsting p = bimapping p (iso id id)
是否一样好?
答案 0 :(得分:3)
感谢您的问题,下一版Control.Lens.Iso
will include firsting
和seconding
。
iso id id
看起来有点难看。让我们尝试分开。
type Iso s t a b =
forall f p . (Functor f, Profunctor p) =>
p a (f b) -> p s (f t)
--plain :: Iso s t s t
--plain = iso id id
plain :: (Functor f, Profunctor p) => p s (f t) -> p s (f t)
plain = id
所以你可以将你的实现减少到
firsting p = bimapping p id
这可能是最简洁的形式。如果你真的想要了解它,请继续阅读。
概述bimapping
bimapping :: (Bifunctor f, Bifunctor g) => AnIso s t a b -> AnIso s' t' a' b' -> Iso (f s s') (g t t') (f a a') (g b b')
bimapping f g = withIso f $ \ sa bt -> withIso g $ \s'a' b't' ->
iso (bimap sa s'a') (bimap bt b't')
并使用first
进行简化,即可获得
firsting p = withIso p $ \ sa bt ->
iso (first sa) (first bt)
我认为这是一个特别明确的表达。它使用withIso
将p
分解为构成同构的两个函数,使用first
提升每个函数以应用于bifunctor的第一个参数,然后将它们打包回来iso
。如果相关的bifunctor具有优于first
的优化bimap
,那么这比bimapping
更好,那么这也会比使用iso
的实现更快。
内联firsting p = withIso p $ \ sa bt ->
dimap (first sa) (fmap (first bt))
给出了
withIso
最后,内联Control.Lens.Internal.Iso
(挖掘firsting p =
case p (Exchange id Identity) of
Exchange sa bt ->
dimap (first sa) (fmap (first (runIdentity #. bt)))
,我们可能不应该这样做),
plain
顺便说一下,没有冗余上下文的plain :: p s (f t) -> p s (f t)
的类型签名是
plain :: Equality s t s t
这与
完全相同using Microsoft.VisualStudio.PlatformUI;
....
//Then you get an event
VSColorTheme.ThemeChanged += VSColorTheme_ThemeChanged;