Type fgx = g. gx

I don’t understand why the function defined as

fgx = g . gx 

has type

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

I would think it would be a type

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

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

+6
source share
2 answers

Please note that the application application has the highest priority; operators come later.

So, the term g . gx g . gx first applies g to x , and then compiles the result and g . If x is of type b , g must be of type b -> c . Since we compose g with gx (the last of type c ), c must be the type of function returning b , so c = a -> b . Now type g is equal to b -> a -> b , and type g . gx g . gx - a -> (a -> b) ; type f turns out to be (b -> a -> b) -> b -> a -> a -> b .

If you need something like (a -> a) -> a -> a , you can try one of these

 fgx = g (gx) fgx = (g . g) x fgx = g . g $ x fg = g . g 
+11
source

The idea is to understand the operator (.) , It has a type

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

It takes two functions, each with one parameter and their compilation, after applying gx alleged compiler g actually g :: a -> b -> c to satisfy the signature (.) :: (b -> c) -> (a -> b) -> a -> c , which takes two functions with one argument. Otherwise, the code will not compile.

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

 λ> let applyTwice g = gg λ> :t applyTwice applyTwice :: (a -> a) -> a -> a λ> applyTwice (*2) 3 12 
+2
source

All Articles