在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必须是相同的类型。
答案 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
}