Haskell 将Iso提升到Bifunctor的第一个参数中
Haskell 将Iso提升到Bifunctor的第一个参数中,haskell,haskell-lens,isomorphism,bifunctor,Haskell,Haskell Lens,Isomorphism,Bifunctor,Control.Lens.Iso包含许多奇妙的函数,用于将Isos提升到有用抽象的各种类型参数中。例如: 任意函子的映射 逆变式函子的逆变式函子 dimapping,lmapping和rmapping用于Profunctors Bifunctor的bimapping 我正在寻找将Iso提升到Bifunctor的第一个参数的函数,但它似乎不在那里。我现在这样定义它: firsting :: Bifunctor f => AnIso s t a b -> Iso (f s
Control.Lens.Iso
包含许多奇妙的函数,用于将Iso
s提升到有用抽象的各种类型参数中。例如:
- 任意
函子的
映射
函子的逆变式
函子逆变式
,dimapping
和lmapping
用于rmapping
sProfunctor
Bifunctor的
bimapping
Iso
提升到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)
这个函数是否已经存在于某个地方,或者是bimapping p(iso id)
与它得到的一样好?更新
由于您的问题,下一版本的Control.Lens.Iso
firsting
和seconding
isoid
看起来有点难看。让我们试着把它拆开
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')
首先使用进行简化
,您可以
firsting p = withIso p $ \ sa bt ->
iso (first sa) (first bt)
我认为这是一个特别明确的表达。它使用with iso
将p
分解为构成同构的两个函数,使用first
将它们中的每一个提升到bifunctor的第一个参数,然后使用iso
将它们打包。如果相关的bifunctor有一个优化的第一个
,它比使用bimap
可以做得更好,那么这也将比使用BIMAPING
的实现更快
内联iso
firsting p = withIso p $ \ sa bt ->
dimap (first sa) (fmap (first bt))
最后,使用Iso
内联(深入Control.Lens.Internal.Iso
,我们可能不应该这样做)
顺便说一下,plain
的类型签名(没有冗余上下文)是
plain :: p s (f t) -> p s (f t)
这与
plain :: Equality s t s t
谢谢你的分解<代码>映射p id
很好。有时,我忽略了所有花哨的同义词,光学只是功能:)@frasertweedale,不客气。我已经编写了seconding
,概括了这两种类型和firsting
,以允许两种不同的BIFunctor(如bimapping
),并建议了我的首选实现。
plain :: Equality s t s t