Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将Iso提升到Bifunctor的第一个参数中_Haskell_Haskell Lens_Isomorphism_Bifunctor - Fatal编程技术网

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
    用于
    Profunctor
    s
  • 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