简体   繁体   English

Haskell中的同构`fmap`

[英]Isomorphic `fmap` in Haskell

Does such a thing exist in Haskell's Prelude? Haskell的Prelude中是否存在这样的事情?

wfmap :: Functor f
      => a
      -> (a -> b)
      -> (b -> a)
      -> (b -> f b)
      -> f a
wfmap x u w g = fmap (w) (g (u x))

In a project I'm working on, I often found myself 'converting' a type to another, process it and 'converting' it back. 在我正在进行的一个项目中,我经常发现自己“转换”了一种类型,处理它并“转换”它。

Reordering the arguments, as leftaroundabout suggests, allows for a tidier definition: 正如左下图所示,重新排序参数允许更整洁的定义:

wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = fmap w . g . u

As for library support, lens provides nifty support for isomorphisms . 至于图书馆支持, 镜头 为同构提供了极好的支持 A bit more broadly, as Gurkenglas notes... 更广泛地说,正如Gurkenglas所说的......

Functor f => (b -> fb) -> a -> fa is also called Lens' ab and is the centerpiece of the lens library. Functor f => (b -> fb) -> a -> fa也称为Lens' ab ,是镜头库的核心。

Without diving into the details of how and why that works, one consequence is that your function might be defined as: 如果不深入了解其工作方式和原因的细节,一个结果就是您的功能可能被定义为:

wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = (iso u w) g

Or even: 甚至:

wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap = iso

wfmap is just (a specialised version of) iso , which gives out a function which can be used to convert an b -> fb function on the isomorphism "destination" to an a -> fa one on the isomorphism "source". wfmap只是( iso一个特殊版本),它提供了一个函数,可以用来将同构“destination”上的b -> fb函数转换为同构“source”上的a -> fa

It is also worth mentioning mapping , which can be used for the somewhat different purpose of applying fmap on the other side of an isomorphism: 值得一提的是mapping ,它可以用于在同构的另一侧应用fmap不同目的:

GHCi> :t \u w g -> over (mapping (iso u w)) (fmap g)
\u w g -> over (mapping (iso u w)) (fmap g)
  :: Functor f => (s -> a) -> (b -> t) -> (a -> b) -> f s -> f t
GHCi> :t \u w g -> under (mapping (iso u w)) (fmap g)
\u w g -> under (mapping (iso u w)) (fmap g)
  :: Functor f => (s -> a) -> (b -> a1) -> (a1 -> s) -> f b -> f a

Finally, note that iso uw can be replaced by any Iso you might find in the libraries or have predefined elsewhere. 最后,请注意, iso uw可以替换为您在库中找到的任何Iso ,或者已在其他地方预定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM