Haskell 中缀数据构造函数运算符的说明

Haskell 中缀数据构造函数运算符的说明,haskell,Haskell,我在读一篇有趣的博文,名为,其中包括: 为此,我们需要一个表示非空列表的类型。幸运的是,Data.List.NonEmpty中现有的非空类型正是这样。其定义如下: 请注意,非空a实际上只是a和普通(可能是空的[a])的元组。通过将列表的第一个元素与列表的尾部分开存储,可以方便地对非空列表进行建模:即使[a]组件为[],a组件也必须始终存在 关于:|我唯一能找到的地方是对的评论,这意味着我需要对该问题/讨论有一些了解,并解析格式 是否有相关文档(我的搜索没有结果)以及对其使用的简单解释?我不明白,

我在读一篇有趣的博文,名为,其中包括:

为此,我们需要一个表示非空列表的类型。幸运的是,Data.List.NonEmpty中现有的非空类型正是这样。其定义如下:

请注意,非空a实际上只是a和普通(可能是空的[a])的元组。通过将列表的第一个元素与列表的尾部分开存储,可以方便地对非空列表进行建模:即使[a]组件为[],a组件也必须始终存在

关于
:|
我唯一能找到的地方是对的评论,这意味着我需要对该问题/讨论有一些了解,并解析格式

是否有相关文档(我的搜索没有结果)以及对其使用的简单解释?我不明白,因为我只是偶尔和哈斯克尔一起把脚趾浸在水里


任何帮助或见解都将不胜感激。

类型的全名为
Data.List.NonEmpty

您可以找到详细信息

在haskell库中,有一个站点是搜索函数、类型等的良好起点

编辑:如果你混淆了
:|
的意思,那么这里有一些解释

在haskell中,您可以定义自定义运算符,如
$
。同样,您可以使用自定义“名称”创建中缀构造函数

所以你可以自己定义一个:

data MyType = Integer :++ Integer
并将其用作

someVal :: MyType
someVal = 1 :++ 2


请注意,它必须以
(感谢@Ben)

:|
只是构造函数的名称开始。这基本上与这样做相同:

数据非空2 a=(:|)a[a]
或者这个:

data NonEmpty3 a=nonemptyconstructor a[a]
(:|)=无空构造函数
构造函数名称必须以冒号开头才能用作中缀运算符,但除此之外,它只是一个普通构造函数,您也可以将其用作运算符


现在,为什么有人需要这个?实际上,这只是因为
1:|[2,3,4]
读写比
ConstructorName 1[2,3,4]
好得多

数据声明定义了
:|
,而不是使用预定义的
:|
运算符

考虑一下(伪)Haskell中如何定义
[]
的常用示例:

这里,
被定义为一个操作符,该操作符创建一个列表,给定一个
a
类型的元素和另一个
[a]
类型的列表

任何类型都可以创建中缀构造函数,就像您可以定义中缀运算符一样。中缀构造函数和中缀运算符之间的区别在于,构造函数可以而且必须以
开头。(
(:)
本身就是一个简单的例子,从一个
开始并仅由它组成)

还可以定义类型级中缀构造函数。比如说,

type f :+: g = Either f g

嗨,塔莱克斯。我问的是关于
:|
不是
非空的
。很抱歉造成混淆。您对
:|
特别感兴趣,还是想了解中缀构造函数的一般知识?:|特别是。例如,我不知道如何在没有运算符的情况下重写构造函数,如果这有助于显示我的无知。我明白了<代码>:|
在这里没有特殊意义。您可以将其替换为
|:+
或任何其他标点符号组合。它类似于构造函数名称,但由标点符号而不是字母组成。@talex顺便说一句,它不能是标点符号的任何组合。与普通标识符被分为以大写字母开头的“构造函数”和以小写字母(或下划线)开头的“变量”非常相似,符号构造函数必须以
开头来区分。(基本上,冒号是大写的)啊,程序员的懒惰。我早该知道的!:)谢谢。@iain我不认为这是懒惰。Haskell程序员经常将函数(较少使用构造函数和数据类型)定义为运算符,这仅仅是因为它更适合特定用例。一个很好的例子是一元绑定操作符
>=
:像
m>>=func1>>=func2>>=func3
bind(bind(bind m func1)func2)func3
容易阅读。另一个很好的例子是库,它允许在Haskell中使用操作符将音乐片段组合在一起进行音乐创作。
foo :: MyType -> Integer
foo (a :++ b) = a
data [] a = [] | (:) a ([] a)  -- data [a] = [] | a : [a]
type f :+: g = Either f g