
Hi, I have a basic question concerning function composition. I have used http://www.haskell.org/tutorial/functions.html to write a composition function: Prelude> let f°g = f g Prelude> let p = (*2) Prelude> let q = (+3) Prelude> p°q 4 14 Prelude> :t (°) (°) :: (t1 -> t) -> t1 -> t If I understand well, this means that the infix operator "°" takes a function of type t1, i.e. g in f°g, and applies f on it, which takes a type t1 as input and returns f(g) which is of type t. The final result is of type t. So the first argument is represented above by "(t1->t)", and the second by "t1", the final result being of type t. However, I am not able to get the type of p°q Prelude> :t p°q <interactive>:1:3: Couldn't match expected type `Integer' with actual type `Integer -> Integer' In the second argument of `(°)', namely `q' In the expression: p ° q Prelude> What's the problem here? How can I obtain the type of p°q? Thanks in advance, TP

What you've actually defined is function application. Function composition has a different type: (.) :: (b -> c) -> (a -> b) -> a -> c (I'd read this as: compose takes a function from b to c, a function from a to b, and something of type a, and produces a c.) You ran into an order of operations issue that masked this bug: p . q 4 /= (p . q) 4 Since you're working through this I don't want to give away the actual definition of function composition, but be sure to follow the type. On 2012-01-15 16.17.24 +0100, TP wrote:
Hi,
I have a basic question concerning function composition. I have used http://www.haskell.org/tutorial/functions.html to write a composition function:
Prelude> let f�g = f g Prelude> let p = (*2) Prelude> let q = (+3) Prelude> p�q 4 14 Prelude> :t (�) (�) :: (t1 -> t) -> t1 -> t
If I understand well, this means that the infix operator "�" takes a function of type t1, i.e. g in f�g, and applies f on it, which takes a type t1 as input and returns f(g) which is of type t. The final result is of type t. So the first argument is represented above by "(t1->t)", and the second by "t1", the final result being of type t.
However, I am not able to get the type of p�q
Prelude> :t p�q
<interactive>:1:3: Couldn't match expected type `Integer' with actual type `Integer -> Integer' In the second argument of `(�)', namely `q' In the expression: p � q Prelude>
What's the problem here? How can I obtain the type of p�q?
Thanks in advance,
TP
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sunday 15 January 2012, 16:17:24, TP wrote:
Hi,
I have a basic question concerning function composition. I have used http://www.haskell.org/tutorial/functions.html to write a composition function:
Prelude> let f°g = f g
This does not what you probably expect. That definition means (°) = ($) is just function application, or, in other words, (°) is the identity function restricted to function types. If I'm correct in suspecting you want function composition, Prelude> let f°g = f . g Prelude> let (°) = (.) Prelude> let (f ° g) x = f (g x) are possible ways to obtain that.
Prelude> let p = (*2) Prelude> let q = (+3)
These two lead to the surprise below.
Prelude> p°q 4
This is parsed as p ° (q 4)
14 Prelude> :t (°) (°) :: (t1 -> t) -> t1 -> t
(°) is the identity restricted to function types.
If I understand well, this means that the infix operator "°" takes a function of type t1, i.e. g in f°g,
it may be a function, but need not, it could also be a non-function value like [], True, ...
and applies f on it, which takes a type t1 as input and returns f(g) which is of type t. The final result is of type t. So the first argument is represented above by "(t1->t)", and the second by "t1", the final result being of type t.
However, I am not able to get the type of p°q
Prelude> :t p°q
<interactive>:1:3: Couldn't match expected type `Integer' with actual type `Integer -> Integer' In the second argument of `(°)', namely `q' In the expression: p ° q Prelude>
What's the problem here?
1. The monomorphism restriction. You have bound p and q Prelude> let p = (*2) Prelude> let q = (+3) with simple pattern bindings (plain variable name, no function arguments in the binding) and without type signature. The inferred most general type for both is Num a => a -> a which is a constrained polymorphic type. The monomorphism restriction (language report, section 4.5.5) says such bindings must have a monomorphic type. By the defaulting rules (section 4.3.4), the type variable is defaulted to Integer to obtain a monomorphic type. Hence in your session, you have p, q :: Integer -> Integer Now, (°) :: (a -> b) -> a -> b, and matching p's type with the type of (°)'s first argument, a = b = Integer. But if we try to match q's type with the type of (°)'s second argument, that type has already been determined to be Integer here, so q's type (Integer -> Integer) doesn't match. 2. Even with the monomorhism eliminated, by one (or more) of a) binding p and q with a function binding (let p x = x * 2) b) giving a type signature for the binding c) disabling the MR (Prelude> :set -XNoMonomorphismRestriction) you still get something probably unexpected. now p :: Num a => a -> a q :: Num b => b -> b unifying p's type with the type of (°)'s first argument, (p °) :: Num a => a -> a Now we must unify a with q's type, thus (p ° q) :: (Num b, Num (b -> b)) => b -> b
How can I obtain the type of p°q?
Eliminate the MR from the picture.
Thanks in advance,
TP
participants (3)
-
Daniel Fischer
-
Mike Burns
-
TP