将Iso提升为Bifunctor的第一个参数

时间:2015-12-08 11:03:36

标签: haskell lens isomorphism bifunctor

Control.Lens.Iso包含许多很棒的函数,用于将Iso提升为有用抽象的各种类型参数。例如:

    对于任意mapping s ,
  • Functor {li> contramapping Contravariant仿函数
  • {li> dimappinglmappingrmapping 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) 是否一样好?

1 个答案:

答案 0 :(得分:3)

更新

感谢您的问题,下一版Control.Lens.Iso will include firstingseconding

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)

我认为这是一个特别明确的表达。它使用withIsop分解为构成同构的两个函数,使用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;