在 Haskell 中,“Cons” 和 “:-:” 意味着什么?

10

LYAHFGG中的一章中提到,列表被定义为:

data List a = Cons a (List a) deriving (Show, Read, Eq, Ord)

除了Cons以外,我理解这里的大部分内容。当我在ghci中尝试:t Cons:i Cons时,我得到了一个不在作用域内的错误。在本章后面,它还谈到了:-:以及它与Cons相同。

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

但是我真的不明白这个:-:是什么意思。

在另一个资源中,在关于数据类型的部分,他们定义了以下数据类型:

data Expr = X
      | Const Int
      | Expr :+: Expr
      | Expr :-: Expr
      | Expr :*: Expr
      | Expr :/: Expr
      | IfZero Expr Expr Expr
      deriving (Eq, Ord)

IfZero p q rif p == 0 then q else r相同。这是一样的吗?我主要不明白两个:的意思,它们是否是强制语法还是只是样式选择。


3
我建议您了解数据声明语法。那些是构造函数。 - Thomas M. DuBuisson
@ThomasM.DuBuisson 你有什么资源可以推荐吗?这两个都解释得不是很清楚。 - user6731064
1
我一直觉得Wikibooks是一个被低估的资源(https://en.wikibooks.org/wiki/Haskell/Type_declarations),但LYAH也有一个关于这个主题的章节(http://learnyouahaskell.com/making-our-own-types-and-typeclasses#algebraic-data-types)。 - Thomas M. DuBuisson
@ThomasM.DuBuisson 是的,这就是我所说的LYAH的章节。也许我没有很好地表达我的问题。这本书似乎没有准确解释 :-: 的含义。我在这一章中找不到该函数的定义或提及。 - user6731064
1
那就是定义。它构造了一个类型为List a的值。Empty是一个有效的表达式,表示一个空列表。Cons 1 Empty是一个有效的表达式,其值的类型为List Int - Thomas M. DuBuisson
一旦您解决了作用域问题,:t Cons 的输出将为 Cons :: a -> List a -> List a,而 :i Cons 的输出将是您在问题中询问的那一行。 - Marcel Besixdouze
2个回答

15
data List a = Cons a (List a) deriving (Show, Read, Eq, Ord)

I understand what most of this means apart from Cons. When I try :t Cons and :i Cons in ghci I get a not in scope error.

在你使用Cons之前,需要加载带有data声明的Haskell源文件。或者,你可以直接在GHCi中输入该data行。

对于严肃的代码来说,最好将其放在一个文件中并进行加载。这是因为学习过程通常涉及到对文件进行一些修改、重新加载、在GHCi中尝试一些测试、再次修改文件等操作。在GHCi中进行这些操作很麻烦。

无论如何,Cons只是构造函数的名称--它是任意的名称。如果你愿意,你可以使用data List a = Foobar a (List a) ....并将其命名为Foobar。不过,Cons是一个历史悠久的名称,起源于Lisp。

:-:是构造函数的另一个任意名称,除了它可以被用作中缀。也就是说,可以用1 :-: someList代替Cons 1 someList


啊,谢谢。我在试验的时候已经开始怀疑是这个问题了。我觉得喝太多咖啡而睡眠不足是个坏主意。 - user6731064

8

:-:只是一个数据构造函数的中缀名字。你可以将该data声明视为等同于以下内容:

data List a = Empty | (:-:) a (List a)

从语义上讲,使用 (:-:)Cons 没有区别,但读起来更加舒适。

1 :-: 2 :-: 3 :-: 4 :-: Empty

比任何一个更好
Cons 1 (Cons 2 (Cons 3 (Cons 4 Empty)))

或者

1 `Cons` (2 `Cons` (3 `Cons` (4 `Cons` Empty)))

1
只要将其包含在反引号中,您也可以在中缀位置使用Cons。任何以:开头的构造函数名称(例如::-:)都被特殊处理为中缀构造函数,并且在不将其包含在反引号中的情况下使用。 - chepner
@chepner 没错,但是反引号本身也很烦人。 - isekaijin
我在Hoogle中找不到:-:,而且GHCi似乎也无法识别它。它与:有什么不同? - Zoey Hewll
@ZoeyHewll :-: 不在标准库中,你需要先定义它。 - isekaijin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接