Reputation: 13
I'm trying to understand Haskell function types right now. Let's say I want to compose two functions f1 and f2 (suppose I don't know their definition). The function signature of f2 . f1 is:
f1 . f2 :: (Fractional (a -> a), Num a) => a -> (a -> a) -> a -> a
How do I read this signature and more specifically, how do I know how to apply arguments to this composition?
e.g. how can I read the type information of f1 . f2 to be able to write valid expressions like
(f1 . f2 2) 3 4
(f1 2. f2 2) 4
Upvotes: 0
Views: 98
Reputation: 92117
That signature means you haven't composed them correctly. You don't get a type error, because in theory some madman might give functions a Fractional
instance, but in real life that never happens. So there is no set of arguments you can apply to (f1 . f2)
that will typecheck.
Instead, back up and look at the types of f1
and f2
. What are they? I predict that they are both two-argument functions, because your type is the one I get when I write
:t (/) . (+)
(/) . (+)
:: (Fractional (a -> a), Num a) => a -> (a -> a) -> a -> a
You can't really compose a two-argument function, because composition is for one-argument functions. But you can partially apply the functions before composing, if you like, to make them into one-argument functions. And that's exactly what you've done in your last example, which works fine:
Prelude> f1 = (/)
Prelude> f2 = (+)
Prelude> (f1 2 . f2 2) 4
0.3333333333333333
Upvotes: 2