Only one of these is actually built-in function application syntax: the one you call ()
. (Note that it doesn't actually require any parentheses though, just juxtaposition.) All Haskell expressions ultimately boil down to this syntax; infix-operator style is just syntactic sugar for it. The examples you've tried desugar thus:
〖〗: 100 / fromIntegral( length [1..10] )
≡ (/) 100 (fromIntegral (length [1..10]))
〖〗: 100 / fromIntegral . length [1..10]
≡ (/) 100 ((.) fromIntegral (length [1..10]))
〖〗: 100 / fromIntegral $ length [1..10]
≡ ($) ((/) 100 fromIntegral) (length [1..10])
The reason they desugar so differently is infix precedence rules: every infix operator comes with a fixity declaration. The ones relevant here:
Prelude> :i .
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in ‘GHC.Base’
infixr 9 .
Prelude> :i $
($) ::
forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).
(a -> b) -> a -> b
-- Defined in ‘GHC.Base’
infixr 0 $
Prelude> :i /
class Num a => Fractional a where
(/) :: a -> a -> a
...
-- Defined in ‘GHC.Real’
infixl 7 /
What this tells us is: .
binds more tightly than /
, which binds more tightly than $
. So, for example w . x / y $ z
is parsed as ((w . x) / y) $ z
, which is sugar for
($) ((/) ((.) w x) y) z
(Function application itself – the one you called ()
– always binds more tighly than any infix operator).
Ok, the diet expressions above look confusing, so let's go back to a sugared form again but still with explicit parenthesis-grouping:
〖〗 ≡ 100 / (fromIntegral (length [1..10]))
〖〗 ≡ 100 / (fromIntegral . (length [1..10]))
〖〗 ≡ (100 / fromIntegral) $ (length [1..10])
It should be immediately clear that 〖〗 can't be right, regardless of what the operators actually do: you're trying to divide a number by a function, that doesn't make sense! The low precedence of the $
operator is specifically intended to separate expressions – basically whenever you see this operator, you can just imagine that each of the operands has parentheses around it.
〖〗 looks sensible enough parsing-wise, however it does not make sense type-wise: .
is not a function application operator but a function composition operator. I.e. both of its operands should be functions, but (length [1..10])
is already the result of applying a function to its (only) argument, so you're trying to compose a function with a number.
You could actually write this expression using the composition operator, but you'd have to compose the functions before applying either of them to an argument (and only apply the argument to the composition-chain):
〖′〗: 100 / (fromIntegral . length) [1..10]
≡ 100 / (\x -> fromIntegral (length x)) [1..10]
≡ 100 / fromIntegral (length [1..10])
≡ 〖〗
Now as for $
, that is actually a function application operator, so you can use it too. Just, you need to make proper use of its low fixity, and make sure it does not interfere with the higher-precedence /
operator:
〖′〗: 100 / (fromIntegral $ length [1..10])
≡ 100 / ((fromIntegral) (length [1..10]))
≡ 100 / fromIntegral (length [1..10])
≡ 〖〗