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