问题
Sometimes I have two functions of the form:
f :: a -> (b1,b2)
h :: b1 -> b2 -> c
and I need the composition g. I solve this by changing h to h':
h' :: (b1,b2) -> c
Can you please show me (if possible) a function m, so that:
(h . m . f) == (h' . f)
Or another way to deal with such situations. Thanks.
回答1:
What you're looking to do is to take a function that operates on curried arguments, h
, and apply it to the result of f
, which is a tuple. This process, turning a function of two arguments into a function that takes one argument that is a tuple, is called uncurrying. We have, from 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.
So now we can write:
f :: a -> (b,c)
f = undefined
h :: b -> c -> d
h = undefined
k :: a -> d
k = uncurry h . f
Another tricky way to think of this is via an applicative functor,
k = (h <$> fst <*> snd) . f
Idea from Conor McBride, who'd write it as: (|f fst snd|) . f
I think.
回答2:
What you want to do is uncurry h
. This function takes a -> b -> c
and converts it into (a, b) -> c
.
uncurry h . f
来源:https://stackoverflow.com/questions/6237259/function-composition-in-haskell-with-tuple-arguments