简体   繁体   中英

Type of f g x = g . g x

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!

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

So, the term g . gx g . gx 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 gx (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 . gx g . gx 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

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 gx 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM