有人可以解释这个函数以及如何在 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)
| :}
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 likeCons
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)
| :}