New to Haskell, and I hit a simple error on this piece of an expression
matches !! length . count
cannot mix '!!' [infixl 9] and '.' [infixr 9] in the same infix expression
This surprised me - why do these operators share a precendence? What prevented Haskell's designers from establishing (.)
at a higher precendence than (!!)
?
I can't imagine this was simply overlooked, so I assume there is a rationale here that I am missing.
Note I realize that applying (!!)
to the function that is composed by (.)
would still result in an error at compile time. I'm curious about why Haskell was designed in a way that allowed for this unexpected error message.
I went digging. There likely is no rhyme or reason for the two infix operators having the same precedence. In the Haskell 1.0 report, released in 1990, the (!!)
operator was found in the PreludeList.hs file and the (.)
operator was in the Prelude.hs file. Because they deal with completely different things (function composition vs list indexing), and they were in completely different files, it's highly likely that they were not cross coordinated.
Moreover, within the report, these functions in the Prelude were barely mentioned. (.)
was just mentioned in a one liner as the composition function and (!!)
was not mentioned at all outside of the actual source file.
The reason for that ought to be more or less obvious. The Prelude is useful, but it's not the reason Haskell was developed, and it's not the hard, interesting part of language design. Haskell was more about lambda calculus and category theory than list indexing. So it's not surprising that not a lot of thought (or at least not a lot of documentation!) went into exactly what precedence various operators were.
Haskell has a lot of operators. Running
grep -hor '^infix[lr]\{0,1\} .*$' ghc/libraries/ | sort -u
inside my GHC head I get back 137 operators. Not quite all of these are exposed, but still: since precedence has to be between 0
and 9
inclusive, clashes are inevitable.
$
should be lower than pretty much everything (fixity 0)>>=
should be higher than $
(fixity 1)||
should be higher than >>=
(fixity 2)&&
should be higher than ||
(fixity 3)==
should be higher than &&
(fixity 4)++
should be higher than ==
(fixity 5)+
should be higher than ++
(fixity 6)*
should be higher than +
(fixity 7)^
should be higher than *
(fixity 8)!!
should be higher than ^
(fixity 9).
should be higher than pretty much everything (fixity 9)So there isn't really space to differentiate the precedence of !!
and .
. Also, I don't think there is much precedent for either .
or !!
to be expected to have higher precedence.
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