:, infix operator, infix constructor, et cetera

There is something called infix constructors and something else called infix operators. I'm guessing that an infix operator is really a function, and an infix constructor I don't know what it is. How would you guys describe them? (*) More questions. I learned how to define (++), and then I wanted to see how (:) would be defined. The Haskell 98 Report mentions that -- The (:) operator is built-in syntax, and cannot legally be given -- a fixity declaration; but its fixity is given by: -- infixr 5 : What does ``built-in syntax'' mean? Paul Hudak, in ``The Haskell School of Expression'' mentions that he defines (:) legally, in Appendix A. After writing data [a] = [] | a : [a] -- more pseudo-code infixr 5 : and making a couple of observations about it, he writes: ``The way (:) is defined here is actually legal syntax. Infix constructors are permitted in *data* declarations, and are distinguished from infix operators (for pattern-matching purposes) by the fact that they must begin with a colon (a property trivially satisfied by ":").'' So I'm not sure what ``legal syntax'' and ``pseudo-code'' exactly mean. The program
module Main where
data [a] = [] | a : [a] infixr 5 :
main = putStrLn "hello world"
gives %runhugs.exe Colon.lhs runhugs: Error occurred ERROR "Colon.lhs":3 - Syntax error in data declaration (unexpected `[') (*) The 5. What does that 5 do in ``infixr 5 :''?

Daniel C. Bastos wrote:
There is something called infix constructors and something else called infix operators. I'm guessing that an infix operator is really a function, and an infix constructor I don't know what it is. How would you guys describe them?
An "infix operator" is literally a normal function with a funny name, for example (++). If a function name consists only of symbols, not letters, it works infix instead of prefix. On the other hand, you can take a normal function name and make it infix using backticks: filter odd [1,2,3] odd `filter` [1,2,3] An "infix constructor" is a constructor rather than a function. Normally, functions start with a lowercase letter, and constructors start with an uppercase letter. But when the names are symbols, everything becomes infix, and an infix constructor starts with a ":", and an infix function starts with any other symbol. data Tree x = Leaf x | Branch (Tree x) (Tree x) data Tree x = Leaf x | (Tree x) :## (Tree x)
I learned how to define (++), and then I wanted to see how (:) would be defined.
It's a constructor. Like Leaf and Branch in the example above. If the list type wasn't already defined, you could define it as data List x = Node x (List x) | End and then write lists as Node 1 (Node 2 (Node 3 End)) However, that's a lot of typing, so the actual definition looks more like data [x] = x : [x] | [] But that won't compile, because it doesn't obey the syntax rules of Haskell. You could, however, write data List x = x : (List x) | End and it would work. 1 : (2 : (3 : End))
What does ``built-in syntax'' mean?
The way lists are written (most especially the "[1,2,3]" syntax) is hard-wired into the compiler and cannot be changed. (Similarly for strings, actually.)
The program
data [a] = [] | a : [a] infixr 5 :
gives
%runhugs.exe Colon.lhs runhugs: Error occurred ERROR "Colon.lhs":3 - Syntax error in data declaration (unexpected `[')
It doesn't like you calling the type "[x]". If you call it "List x" like I showed above, it should work.
What does that 5 do in ``infixr 5 :''?
5 is the precedence. You know how "2 + 3 * 4" is treated as "2 + (3 * 4)"? That's because (*) has a higher precedence than (+).

Andrew Coppin wrote:
Daniel C. Bastos wrote: But that won't compile, because it doesn't obey the syntax rules of Haskell. You could, however, write
data List x = x : (List x) | End
and it would work.
1 : (2 : (3 : End))
Except that (for no particularly good reason) ":" is a reserved symbol that always refers to the Prelude list version. You could define a similar name like: data List x = x :- (List x) | End 1 :- (2 :- (3 :- End)) Isaac

Isaac Dupree wrote:
Andrew Coppin wrote:
Daniel C. Bastos wrote: But that won't compile, because it doesn't obey the syntax rules of Haskell. You could, however, write
data List x = x : (List x) | End
and it would work.
1 : (2 : (3 : End))
Except that (for no particularly good reason) ":" is a reserved symbol that always refers to the Prelude list version. You could define a similar name like:
Really? That's interesting... AFAIK, according to the Report, it shouldn't be. I just tested. GHC won't let me, WinHugs will. Hmm...

On Sun, Aug 26, 2007 at 01:35:33PM +0100, Andrew Coppin wrote:
Isaac Dupree wrote:
Except that (for no particularly good reason) ":" is a reserved symbol
Really? That's interesting... AFAIK, according to the Report, it shouldn't be.
It is; from http://haskell.org/onlinereport/syntax-iso.html consym -> (: {symbol | :})<reservedop> reservedop -> .. | : | :: | = | \ | | | <- | -> | @ | ~ | =>
I just tested. GHC won't let me, WinHugs will. Hmm...
Sounds like a WinHugs bug if you haven't enabled extensions. Thanks Ian
participants (4)
-
Andrew Coppin
-
dbast0s@yahoo.com.br
-
Ian Lynagh
-
Isaac Dupree