The composition of the Haskell function, type (.) (.) And how it is presented

So, I know that:

(.) = (fg) x = f (gx) 

And this is type (B-> C) β†’ (A-> B) β†’ A-> C But what about:

 (.)(.) = _? = _? 

How is this presented? I thought:

 (.)(.) = (fg)(fg)x = f(g(f(gx))) // this (.)(.) = (fgh)x = f(g(hx)) // or this 

But as far as I tried to get its type, this does not match what GHCi tells me. So what is "_?"

Also - what does the function / operator $ do?

+3
types operator-keyword haskell function-composition
source share
2 answers

Firstly, you are careless with your notation.

 (.) = (fg) x = f (gx) -- this isn't true 

What is true:

 (.) fgx = (fg) x = f (gx) (.) = \fgx -> f (gx) 

And its type is set

 (.) :: (b -> c) -> (a -> b) -> a -> c -- nb lower case, because they're type *variables* 

In the same time

 (.)(.) :: (a -> b -> d) -> a -> (c -> b) -> c -> d -- I renamed the variables ghci gave me 

Now open

 (.)(.) = (\f' g' x' -> f' (g' x')) (\fgx -> f (gx)) = \g' x' -> (\fgx -> f (gx)) (g' x') = \g' x' -> \gx -> (g' x') (gx) = \fy -> \gx -> (fy) (gx) = \fygx -> fy (gx) = \fygx -> (fy . g) x = \fyg -> fy . g 

And ($) ?

 ($) :: (a -> b) -> a -> b f $ x = fx 

($) is just a function of the application. But while the application function through matching has high priority, the application function through ($) has low priority.

 square $ 1 + 2 * 3 = square (1 + 2 * 3) square 1 + 2 * 3 = (square 1) + 2 * 3 -- these lines are different 
+13
source share

As dave4420 mentions,

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

So what is the type (.) (.) ? dave4420 skips this part, so here: (.) takes a value of type b -> c as its first argument, therefore

 (.) :: ( b -> c ) -> (a -> b) -> a -> c (.) :: (d -> e) -> ((f -> d) -> f -> e) 

therefore, we have b ~ d->e and c ~ (f -> d) -> f -> e , and the resulting type (.)(.) is (a -> b) -> a -> c . Substituting, we get

 (a -> d -> e) -> a -> (f -> d) -> f -> e 

Renaming, we get (a -> b -> c) -> a -> (d -> b) -> d -> c . This is a function f that expects a binary function g , a value x , a unary function h and another value y :

 fgxhy = gx (hy) 

This is the only way to implement this type: gx :: b -> c , hy :: b and so gx (hy) :: c , if necessary.

Of course, in Haskell, a β€œunary” function is such that it expects one or more arguments; likewise, a binary function is such that it expects two or more arguments. But at least two (therefore, the use of, for example, succ out of the question).


We can also solve this by writing equations, combinators -style 1 . Rational reasoning is easy :

 (.) (.) xyzwq = ((.) . x) yzwq = (.) (xy) zwq = (xy . z) wq = xy (zw) q 

We simply add as many variables as needed to the mix, and then apply the definition back and forth. q was superfluous here, so we can throw it away and get the final definition,

 _BB xyzw = xy (zw) 

(coincidentally, (.) is known as B -combinator ).


1 abc = (\x -> ... body ...) equivalent to abcx = ... body ... , and vice versa, provided that x does not appear among {a,b,c} .

+6
source share

All Articles