Haskell 列出以数字开头的数据类型

Haskell 列出以数字开头的数据类型,haskell,Haskell,我正在尝试在Haskell中执行类似于上面代码的操作。我想为列表创建一个数据类型,该列表必须以数字开头,但可以包含小写字符或尾部数字。在Haskell中,列表不是“特殊”类型。事实上,我们可以这样定义它: data Identifier = Identifier [Num:(Char|Num)] 这意味着编译器不必理解什么是列表,以及列表是如何工作的。因为Haskell[a]只是[]a的另一种表示形式,它只是查看列表的类型构造函数。因此,这意味着对于编译器[a:b]来说,as类型是非感官的,因

我正在尝试在Haskell中执行类似于上面代码的操作。我想为列表创建一个数据类型,该列表必须以数字开头,但可以包含小写字符或尾部数字。

在Haskell中,列表不是“特殊”类型。事实上,我们可以这样定义它:

data Identifier = Identifier [Num:(Char|Num)]
这意味着编译器不必理解什么是列表,以及列表是如何工作的。因为Haskell
[a]
只是
[]a
的另一种表示形式,它只是查看列表的类型构造函数。因此,这意味着对于编译器
[a:b]
来说,as类型是非感官的,因为
(:)
不是类型构造函数,而是数据构造函数

您可以使用第一个字符作为单独的参数对此进行建模,如:

data List a = Empty | Cons a (List a)
因此,我们的
标识符
数据类型排除了两种情况:

  • “空”标识符(完全没有字符);及
  • 字符开头的标识符
  • 您可能需要定义一个
    数字
    类型和
    低位
    类型,这两个类型分别类似于
    Int
    Char
    的子集,以进一步限制类型中可能的值,因为现在
    Int
    的值可以超出
    [0..9]
    范围,和
    Char
    可以有任何字符

    您还可以编写函数将字符串解析为
    标识符
    。事实上,通过正确地“设计”数据类型,您可以排除许多不可能的值,因此编译器可以帮助您确保您的函数不会返回应被视为无效的值

    Haskell中的一些库也使用了上述技术。例如,模块定义了:


    因此,这里我们定义了一个
    NonEmpty
    列表,其中的构造函数强制a
    NonEmpty
    有一个元素,以及一个剩余元素的列表(可能是空的)。

    在Haskell中,列表不是“特殊”类型。事实上,我们可以这样定义它:

    data Identifier = Identifier [Num:(Char|Num)]
    
    这意味着编译器不必理解什么是列表,以及列表是如何工作的。因为Haskell
    [a]
    只是
    []a
    的另一种表示形式,它只是查看列表的类型构造函数。因此,这意味着对于编译器
    [a:b]
    来说,as类型是非感官的,因为
    (:)
    不是类型构造函数,而是数据构造函数

    您可以使用第一个字符作为单独的参数对此进行建模,如:

    data List a = Empty | Cons a (List a)
    
    因此,我们的
    标识符
    数据类型排除了两种情况:

  • “空”标识符(完全没有字符);及
  • 字符开头的标识符
  • 您可能需要定义一个
    数字
    类型和
    低位
    类型,这两个类型分别类似于
    Int
    Char
    的子集,以进一步限制类型中可能的值,因为现在
    Int
    的值可以超出
    [0..9]
    范围,和
    Char
    可以有任何字符

    您还可以编写函数将字符串解析为
    标识符
    。事实上,通过正确地“设计”数据类型,您可以排除许多不可能的值,因此编译器可以帮助您确保您的函数不会返回应被视为无效的值

    Haskell中的一些库也使用了上述技术。例如,模块定义了:


    因此,这里我们定义了一个
    NonEmpty
    列表,其中的构造函数强制a
    NonEmpty
    有一个元素,以及一个剩余元素的列表(可能是空的)。

    在这种情况下,您可以将其写为
    数据标识符=标识符Num[任一字符Num]
    。因此,这里的起始项是一个单独的字段。然而,标识符通常以
    Char
    开头,而不是以
    Num
    开头。我们正在为大学制作一种奇怪的嵌入式语言。如果数字是列表的一部分,这也会起作用吗?不会,因为列表中的元素都具有相同的类型。Haskell并不特别对待列表:如果你写
    [a]
    ,你就写
    []a
    ,用
    []
    类型构造函数。所以事实上,编译器根本不需要理解列表的概念。但是,通过使用字段,您可以使数据类型“更强”,因为(a)不可能定义空标识符,(b)您强制要求第一项是列表。然后,您可以创建一些函数来解析和呈现
    标识符
    。在这种情况下,您可以将其编写为
    数据标识符=标识符Num[或Char Num]
    。因此,这里的起始项是一个单独的字段。然而,标识符通常以
    Char
    开头,而不是以
    Num
    开头。我们正在为大学制作一种奇怪的嵌入式语言。如果数字是列表的一部分,这也会起作用吗?不会,因为列表中的元素都具有相同的类型。Haskell并不特别对待列表:如果你写
    [a]
    ,你就写
    []a
    ,用
    []
    类型构造函数。所以事实上,编译器根本不需要理解列表的概念。但是,通过使用字段,您可以使数据类型“更强”,因为(a)不可能定义空标识符,(b)您强制要求第一项是列表。然后,您可以创建一些函数来解析和呈现
    标识符
    。该语言允许将本来无效的“name”
    []
    用作空列表的类型构造函数和数据构造函数,还允许将
    [x,y,z]
    用作
    x:y:z:[]
    @chepner:yes的语法糖,但我这里的意思是Haskell编译器不需要处理列表类型的差异。但是你确实是对的,有一些语法上的糖分和ond语法
    data NonEmpty a = a :| [a]