Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of f g x = g . g x

Tags:

haskell

It is not clear to me why the function defined as

f g x = g . g x

has the type

f :: (b -> a -> b) -> b -> a -> a -> b

I would have thought it would be of type

f :: (t -> t) -> t -> t

Can anyone explain to me how the expression is broken down? Thanks!

like image 883
SuspiciousPineapple Avatar asked Dec 23 '15 08:12

SuspiciousPineapple


People also ask

What does f G X mean?

f of g of x is also known as a composite function and it is mathematically denoted as f(g(x)) or (f ∘ g)(x) and it means that x = g(x) should be substituted in f(x). It is also read as "f circle g of x". It is an operation that combines two functions to form another new function.

What is f G?

f ◦ g is the composition function that has f composed with g. Be aware though, f ◦ g is not the same as g ◦ f. (This means that composition is not commutative).


2 Answers

Note that function application has the highest priority; operators come later.

So, the term g . g x first applies g to x, and then composes the result and g itself. If x has type b, g must have type b -> c. Since we compose g with g x (the latter of type c), c must be a function type returning b, so c = a -> b. Now, the type of g is b -> a -> b and the type of g . g x is a -> (a -> b); the type of f happens to be (b -> a -> b) -> b -> a -> a -> b.

If you wanted something like (a -> a) -> a -> a instead, you could try one of this

f g x = g (g x)
f g x = (g . g) x
f g x = g . g $ x
f g = g . g
like image 74
lisyarus Avatar answered Oct 16 '22 10:10

lisyarus


The idea is about understanding the (.) operator, it has a type of

(.) :: (b -> c) -> (a -> b) -> a -> c

It takes two functions each with one parameter and compose them, after applying g x the compiler assumed g is actually g :: a -> b -> c in order to satisfy the signature of (.) :: (b -> c) -> (a -> b) -> a -> c which takes two functions with one argument. Otherwise the code won't compile.

And finally if you want the signature f :: (t -> t) -> t -> t you need something like this:

λ> let applyTwice g = g.g
λ> :t applyTwice
applyTwice :: (a -> a) -> a -> a
λ> applyTwice (*2) 3
12
like image 45
concept3d Avatar answered Oct 16 '22 10:10

concept3d