時々、次の形式の関数が 2 つあります。
f :: a -> (b1,b2)
h :: b1 -> b2 -> c
そして、コンポジションgが必要です。h を h' に変更することでこれを解決します。
h' :: (b1,b2) -> c
次のような関数 m を (可能であれば) 示してください。
(h . m . f) == (h' . f)
または、そのような状況に対処する別の方法。ありがとう。
時々、次の形式の関数が 2 つあります。
f :: a -> (b1,b2)
h :: b1 -> b2 -> c
そして、コンポジションgが必要です。h を h' に変更することでこれを解決します。
h' :: (b1,b2) -> c
次のような関数 m を (可能であれば) 示してください。
(h . m . f) == (h' . f)
または、そのような状況に対処する別の方法。ありがとう。
あなたがしようとしているのは、カリー化された引数 で動作する関数を取り、それをタプルであるh
の結果に適用することです。f
2 つの引数の関数を、タプルである 1 つの引数を取る関数に変換するこのプロセスは、uncurryingと呼ばれます。Data.Tupleから:
curry :: ((a, b) -> c) -> a -> b -> c
-- curry converts an uncurried function to a curried function.
uncurry :: (a -> b -> c) -> (a, b) -> c
-- uncurry converts a curried function to a function on pairs.
したがって、次のように記述できます。
f :: a -> (b,c)
f = undefined
h :: b -> c -> d
h = undefined
k :: a -> d
k = uncurry h . f
これを考えるもう 1 つのトリッキーな方法は、Applicative Functor を使用することです。
k = (h <$> fst <*> snd) . f
Conor McBride のアイデアは次のように書いてい(|f fst snd|) . f
ます。
やりたいことはuncurry h
です。この関数はそれを受け取りa -> b -> c
、 に変換し(a, b) -> c
ます。
アンカリー h . へ