Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do (!!) and (.) share precedence 9? [closed]

Tags:

haskell

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.

like image 630
Matt Avatar asked Dec 01 '22 15:12

Matt


2 Answers

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.

like image 107
OmnipotentEntity Avatar answered Dec 05 '22 06:12

OmnipotentEntity


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.

like image 29
Alec Avatar answered Dec 05 '22 06:12

Alec