Haskell's Prelude中是否存在这样的事情?Haskell中的同构`fmap`
wfmap :: Functor f
=> a
-> (a -> b)
-> (b -> a)
-> (b -> f b)
-> f a
wfmap x u w g = fmap (w) (g (u x))
在一个项目中我的工作,我经常发现自己一型“转换”到另一个过程中它和“转换”回来。
Haskell's Prelude中是否存在这样的事情?Haskell中的同构`fmap`
wfmap :: Functor f
=> a
-> (a -> b)
-> (b -> a)
-> (b -> f b)
-> f a
wfmap x u w g = fmap (w) (g (u x))
在一个项目中我的工作,我经常发现自己一型“转换”到另一个过程中它和“转换”回来。
重新排序的参数,如leftaroundabout所暗示的,允许整洁定义:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = fmap w . g . u
至于库的支持,透镜提供nifty support for isomorphisms。有点更广泛,如Gurkenglas指出...
Functor f => (b -> f b) -> a -> f a
也被称为Lens' a b
,是镜头库的核心。
没有在深入的如何以及为什么这样的作品,一个后果是细节,你的函数可以被定义为:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = (iso u w) g
甚至:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap = iso
wfmap
只是( iso
的一个特殊版本,它给出了一个函数,它可以用来将同构“目标”上的一个b -> f b
函数转换为一个a -> f a
函数同构“源”。
还值得一提的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
最后,请注意iso u w
可以通过任何Iso
代替你可能会在图书馆中找到或在其他地方预定义。
感谢您的支持! :) – iluvAS
把'x :: a'作为最后一个参数会更有意义吗? – leftaroundabout
@leftaroundabout哦,是的,它的确如此。感谢您指出了这一点。但这只是伪代码来解释我的问题。它只是我有很多函数和类型使用类似于这个模式,我想知道是否有更好的方式去做这件事。 – iluvAS
您的'wfmap'在类型中声明了5个参数,但在定义中只有4个参数。我想你只是在类型中增加了一个'a'类型的参数。 – chepner