我在Github上查看的项目中遇到以下代码:
data LispVal = Atom String
| Number Integer
| String String
| Bool Bool
| LispVal :. LispVal -- Cons
:.
语法到底有什么意义?我以前从未见过它?
答案 0 :(得分:5)
:.
只是一个已定义的数据构造函数。你可以在ghci中玩一个想法:
*Main> let a = Atom "test1"
*Main> let b = Atom "test2"
*Main> let c = a :. b
*Main> c
Atom "test1" :. Atom "test2"
我在您的代码中添加了deriving (Show)
,以便在REPL中显示String。你也可以看到它的类型:
*Main> :t (:.)
(:.) :: LispVal -> LispVal -> LispVal
因此,实际上它只是一个函数,它接受两个LispVal
值并返回LispVal
类型的值。
答案 1 :(得分:2)
在Haskell中,"正常"变量以小写字母开头,构造函数名称以大写字母开头。那就是编译器如何区分它们。
Haskell还允许您定义全新的运营商。例如,您可以创建一个名为?+?
的新运算符,该运算符会生成一个字符串,告诉您它的作用:
x ?+? y = show x ++ " + " ++ show y ++ " = " ++ show (x + y)
到目前为止,非常好。
Haskell 也允许构造函数成为运算符。对于"正常"名字,如果第一个字母是小写,它是一个普通变量,如果它是大写的,那么它是一个构造函数。对于运算符,如果第一个字符是:
,则它是构造函数,否则它是"正常"操作
您可能已经看过列表类型,它有两个构造函数[]
(这是魔术)和:
。显然,运算符:
"以"开头。 :
。但你可以自己创造新的:
data Foobar = Int :?? String deriving Show
test = 5 :?? "banana"
只要操作员以:
开头,它就会显示在data
声明中。