2016-12-03 13 views
6

ハスケルのPreludeにこのようなことがありますか?ハスケルの同型の `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が示唆するように、引数を並べ替え

+0

最後の引数として 'x :: a'を取る方がいいでしょうか? – leftaroundabout

+0

@leftaround aboutああ、そうです。それを指摘してくれてありがとう。しかし、これはちょうど私の問題を説明する擬似コードです。そのようなパターンを使用する多くの関数と型があり、これを行うより良い方法があるのだろうかと思っています。 – iluvAS

+2

あなたの 'wfmap'は5つの引数を型で宣言しますが、定義内では4つだけ宣言します。私は型に 'a'型の余分な引数があると思います。 – chepner

答えて

7

は、整然と定義を可能にする:ライブラリサポートとして

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 aLens' a bと呼ばれ、レンズ図書館の目玉です。それがどのように動作するか、なぜの詳細内容に飛び込むなし

、1つの結果は、あなたの関数は、次のように定義されるかもしれないということです。

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に変換するために使用できる関数を出力します同形 "ソース"。

また、同型の他の側にfmapを適用する多少異なる目的のために使用することができmapping、言及する価値がある:最後に

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に置き換えることができることに注意します図書館で見つけたり、他の場所であらかじめ定義したりしているかもしれません。

+0

ありがとう! :) – iluvAS