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

时间:2019-06-05 10:02:29

标签: haskell

data Identifier = Identifier [Num:(Char|Num)]

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

1 个答案:

答案 0 :(得分:4)

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

data List a = Empty | Cons a (List a)

因此,这意味着编译器没有必须了解列表是什么以及列表如何工作。对于Haskell,[a]只是[] a的另一种表示形式,它只是查看列表的类型构造函数。因此,这意味着对于编译器[a : b],因为类型是荒谬的,因为(:) not 类型构造函数,因此它是 data构造函数

您可以将第一个字符作为单独的参数进行建模,例如:

data Identifier = Identifier Int [Either Int Char]

例如,您可以使用以下方式以文本形式表示您的Identifier

import Data.Char(intToDigit)

class Render a where
    render :: a -> String

instance Render Identifier where
    print (Identifier n ns) = intToDigit n : map iprint ns
        where iprint (Left a) = intToDigit a
              iprint (Right b) = b

这里我们的Identifier数据类型因此排除了两种情况:

  1. “空”标识符(完全没有字符);和
  2. Char开头的标识符。

您可能还需要定义Digit类型和Lower类型,它们分别类似于IntChar的子集,以进一步限制可能的值类型,因为现在Int可以具有[0..9]范围之外的值,并且Char可以具有任何字符。

您还可以编写函数以将字符串解析为Identifier。实际上,通过适当地“工程化”数据类型,可以排除很多本来不可能的值,因此编译器可以帮助您确保函数 not 不会返回应考虑的值无效。

Haskell的某些库中也使用了上述技术。例如,Data.List.NonEmpty模块定义了data constructor (:|)

data NonEmpty a = a :| [a]

因此,这里再次定义了一个NonEmpty列表,该列表的构造函数强制一个NonEmpty具有一个元素,以及一个(可能为空)剩余元素的列表。