Search code examples
haskellsyntaxoperatorsspecial-characterstype-signature

Parenthesis around operator symbol in type signature


. :: (a -> b) -> (c -> a) -> c -> b
f . g = \ x -> f (g x)

Why is this definition illegal? Aesthetic choice, or formal necessity?


Solution

  • It's for consistency. Infix operators by themselves aren't expressions whose type or value you could define. The following is also not legal:

    . = \f g x -> f (g x)
    

    ...though that is basically what your definition is desugared to. But for directly defining the value of an infix this way, we need to first disable the special syntactic status, and that's done by wrapping it in parentheses:

    (.) :: (a -> b) -> (c -> a) -> c -> b
    (.) = \f g x -> f (g x)
    

    This is quite the same as defining

    compose :: (a -> b) -> (c -> a) -> c -> b
    compose = \f g x -> f (g x)
    

    ...which can then also be used as an infix, like

    Prelude> map (toEnum `compose` round) $ [110 + sin x * 12 | x<-[0..30]] :: String
    "nxypebkvzsgbhszvkbepyxndclwyqfb"
    

    But you obviously wouldn't write the definition in infix form, like

    `compose` :: (a -> b) -> (c -> a) -> c -> b
    `compose` = \f g x -> f (g x)
    

    ...though you could do

    f`compose`g = \x -> f (g x)