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?
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 "
Function application has an higher precedence over the function composition operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With