Abraham P
Abraham P

Reputation: 15471

Why does function composition require parentheses?

Let's say I want to compose Text.pack with Text.strip.

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

:t (Text.pack) produces: String -> Text

:t (Text.strip) produces: Text -> Text

So substituting strip for (b -> c) gives: b = Text c = Text

Substituting pack for (a -> b) gives: a = String b = Text

Lets verify: :t strip . pack produces: strip . pack :: String -> Text

ok, great lets try it:

strip.pack " example "

Produces:

Couldn't match expected type ‘a -> Text’ with actual type ‘Text’
Relevant bindings include
  it :: a -> Text (bound at <interactive>:31:1)
Possible cause: ‘pack’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘pack "    example     "’
In the expression: strip . pack "    example     "

(strip . pack) " example " works as expected.... why?

Upvotes: 10

Views: 500

Answers (2)

Shoe
Shoe

Reputation: 76240

Function application has an higher precedence over the function composition operator.

Upvotes: 2

chepner
chepner

Reputation: 531055

Function application has a higher priority than composition.

strip.pack " example " is equivalent to strip.(pack " example "). This is one reason why people use $ to "suppress" application until after all the functions have been composed:

strip . pack $ "    example     "

Upvotes: 13

Related Questions