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