在Haskell数据类型中键入类

时间:2009-07-05 05:24:52

标签: haskell types typeclass

在Haskell中,可以定义如下数据类型:

data Point1 = Point1 {
    x :: Integer
  , y :: Integer
}

可以在数据类型中为变量使用类型类吗?如果是这样的话?我意识到有可能将它作为代数数据类型,对每种点都有不同的定义,但我想知道是否有办法以更紧凑和灵活的方式实现这一点。

e.g。这个伪代码的一些东西,它使用函数声明语法:

data Point2 = Point2 {
    x :: (Num a, Ord a) => a
  , y :: (Num a, Ord a) => a
}

目标是允许用户存储 Int Integer Float Double 值数据类型。理想情况下,我想限制它,以便x和y必须是相同的类型。

2 个答案:

答案 0 :(得分:19)

您需要决定是否要对该类型进行存在性或通用量化。通用量化,ala:

data (Num a, Ord a) => Point2 a = Point2 a a

产生了一个证明义务,Num和Ord实例存在于类型'a'但实际上并没有那么多帮助,因为当你通过构造一个值来使用Point类时,它所做的就是给你一个义务那种类型或当你去模式匹配时。

几乎在所有情况下,你最好定义

data Point2 a = Point2 a a deriving (Eq,Ord,Show,Read)

并使您的每个实例都依赖于您想要的额外信息。

instance Num a => Num (Point2 a) where
    ...

instance (Num a, Ord a) => SomeClass (Point2 a) where
    ...

这使您可以传递并构建更少的多余字典,并增加可以使用Point2数据类型的场景数。

另一方面,存在量化可以让你说你根本不关心什么类型(更接近你实际要求的,明智的类型),代价是你不能在它上面使用任何东西,除了由您指定的约束提供的操作 - 这里非常不合适。

答案 1 :(得分:7)

这样的事情?

data (Num a, Ord a) => Point2 a = Point2 {
    x :: a
  , y :: a
}