Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell function composition operator and 'space operator' precedence

Tags:

haskell

First of all, I am very new to Haskell and for the moment I am just trying to prepare for an exam. I have this expression:
reverse . take 3 [1 .. 10] and what I get is an error. Is that because space operator has bigger precedence (10) than . operator (9) and the expression above is equivalent to reverse . (take 3 [1..10]) which is reverse . ([1, 2, 3]) which is a composition between reverse and a list which makes no sense, right? I am trying to make sure I got that right, I didn't really find something similar on the internet.

like image 478
Johnny Avatar asked Nov 10 '21 20:11

Johnny


People also ask

What is the precedence of the composition operator in Haskell?

In Haskell the precedence of an ordinary function call (white space, usually) is of 10. While the composition operator has a precedence of 9. It results in the case where we want to compose functions then apply it to some parameter, we have to parenthesize the composition so as to keep the application in right order.

How do you use the dot operator in Haskell?

We use the dot operator (.) to implement function composition in Haskell. Take a look at the following example code. Here, we have used function composition to calculate whether an input number is even or odd. Here, in the main function, we are calling two functions, noto and eveno, simultaneously.

What is function composition in Haskell?

Haskell - Function Composition. In mathematics, composition is denoted by f {g (x)} where g () is a function and its output in used as an input of another function, that is, f (). Function composition can be implemented using any two functions, provided the output type of one function matches with the input type of the second function.

How do I create a new function in Haskell?

Composing functions is a common and useful way to create new functions in Haskell. Haskell composition is based on the idea of function composition in mathematics. In mathematics, if you have two functions f ( x) and g ( x), you compute their composition as f ( g ( x)). The expression f ( g ( x)) first calls g and then calls f.


2 Answers

You're basically correct. Prefix function application (what you called the "space operator") binds more tightly than any infix operator does. And for completeness, the way to fix the error is to do (reverse . take 3) [1 .. 10] or reverse . take 3 $ [1 .. 10] instead.

like image 200
Joseph Sible-Reinstate Monica Avatar answered Oct 21 '22 12:10

Joseph Sible-Reinstate Monica


I like to use GHCi and look at the types - let's see:

reverse . take 3 [1 .. 10]

error:
• Couldn't match expected type a -> [a1] with actual type [a0]
• Possible cause: take is applied to too many arguments
In the second argument of (.), namely take 3 [1 .. 10]
In the expression: reverse . take 3 [1 .. 10]

:t take 3 [1 .. 10]

take 3 [1 .. 10] :: (Num a, Enum a) => [a]

yields type [a] - let's see what (.) is expecting


:t (.)

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

:t reverse

reverse :: [a] -> [a]

reverse fits the first part of what (.) expects


:t take 3

take 3 :: [a] -> [a]

type fits as the second argument to what (.) expects


:t reverse . take 3

reverse . take 3 :: [a] -> [a]

resulting function takes a list of a and returns a list of a, and so we only need to give it a list of a; being explicit here:

(reverse . take 3) [1 .. 10]
like image 1
Andreas DM Avatar answered Oct 21 '22 12:10

Andreas DM