0

我是一个完整的 Haskell n00b,但我想定义一个新的数据类型,它是一个简单的数字列表。我该怎么做呢?我已经阅读了有关类型声明的 Haskell wikibook 以及其他在线资源,但我似乎无法弄清楚。本质上,这是我尝试过的:

type NumList = [Num]

那没有用,那我该怎么做呢?谢谢您的帮助。

4

3 回答 3

6

Num是一个类,而不是一个类型。选择一种类型;例如IntegerRational可能是不错的选择。

type NumList = [Integer]

但是,这不会创建新类型;它只是为旧类型创建一个新名称。如果你真的想要一个新类型,你可以使用newtype,如

newtype NumList = MkNumList [Integer]

它定义了一个名为的新类型NumList和一个名为 的新数据构造函数MkNumList

于 2013-10-19T01:54:49.743 回答
2

type关键字仅用于类型同义词(已存在的类型的新名称),因此您不能使用Num.

相反,您可以将data关键字与 Haskell 的上下文表示法一起使用:

data Num a => NumList a = NumList [a]

除非我在 ghci 中尝试这样做,否则它会责骂我,因为不推荐使用数据类型上下文。显然你最好使用 GADT。也许是这样的:

data NumList a where
    Empty :: Num a => NumList a
    Singleton :: Num a => a -> NumList a
    Append :: Num a => NumList a -> NumList a -> NumList a
于 2013-10-19T03:09:29.357 回答
1

根据您的确切需要,有几个答案。如果您只想要特定应用程序的数字列表,您可能知道在这种情况下您将使用的确切数字类型,并且应该使用:

type DoubleList = [Double]

(我希望使用更明确的名称,因为与 [Double] 相比,DoubleList 没有任何优势)

如果您想强制使用 NumList 的每个函数都使用Num a上下文(但它不会是自动的,这就是不推荐使用此方法的原因),您可以使用:

data Num a => NumList a = NL [a]

尽管这可能是一个坏主意,但它不会为(Num a) => ...[a]....您在代码中的使用带来任何好处。

如果您不关心列表中数字的确切类型,只要您可以在它们之间进行操作(但不能在两个 NumList 之间),您可以使用存在类型:

data NumList = forall a . (Num a) => NL [a]

这与对象最相似,尽管使用类型擦除并且没有反射,您将无法使用 NumList 做很多事情(可以添加,但到此为止,我很确定您只是在堆积您不需要的困难只是因为你试图在 Haskell 中编写 Java/C++/Other)。

请注意,如果您想为数字列表创建 Num 实例,您可以这样做:

instance (Num a) => Num [a] where ...

我的最终建议确实是[a]在适当的Num a上下文中使用,但如果您认为这是错误的,如果您要获得进一步的指导,您必须提供更多关于您使用这种类型的细节。

于 2013-10-19T13:18:39.283 回答