有人可以解释这个函数以及如何在 Haskell 中输入它(中缀,:-:)

Can someone explain this function and how to type it in Haskell (infix, :-:)

infixr 5 :-:  
data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)  

我们只是写了一个 :-: (List a) 而不是 Cons a (List a)。现在,我们可以像这样在我们的列表类型中写出列表:

ghci> 3 :-: 4 :-: 5 :-: Empty  
(:-:) 3 ((:-:) 4 ((:-:) 5 Empty))  
ghci> let a = 3 :-: 4 :-: 5 :-: Empty  
ghci> 100 :-: a  
(:-:) 100 ((:-:) 3 ((:-:) 4 ((:-:) 5 Empty)))  

我知道 :-: 应该像 Cons 一样工作,但我真的不明白为什么我们被允许这样做以及如何实际键入 infixr 5 :-: .

I get that :-: is supposed to work like Cons but I don't really get why we are allowed to do that …

因为 Haskell report says so. In the grammar the constr is a data constructor. The constr can be a con followed by zero, one or more types, a con followed by record syntax, or a type, an operator conop followed by another type. This is defined as:

constr  →  con [!] atype1 … [!] atypek
        |  (btype | ! atype) conop (btype | ! atype)
        |  con { fielddecl1 , … , fielddecln }

conop 可以是运算符 consym,或者是反引号之间标识符的中缀变体,例如 `foo`,在 grammar section 中写为:

conop    →  consym | ` conid `

grammar指定一个consym定义为:

consym → ( : {symbol })〈reservedop〉

因此冒号后跟一系列符号,并且此类符号不应是保留运算符,如 :::

这意味着除了保留运算符外,您可以使用以冒号 (:) 开头的运算符作为数据构造函数。

… and how to actually type infixr 5 :-:.

您可以通过用 :{:}:

包围它们来编写多行语句
ghci> :{
| infixr 5 :-:  
| data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)
| :}