2009-07-05 113 views
14

在Haskell中,可以定义数据类型,像这样:类型类Haskell中的数据类型

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

可以在一个使用类型类数据类型内部变量?如果是这样如何?我意识到可以将其作为代数数据类型来完成,对于每种类型的点都有不同的定义,但是我想知道是否有办法以更紧凑和更灵活的方式来完成此任务。

例如沿着这线的东西,它使用的函数声明的语法:

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

这样做的目的是允许一个存储诠释整数浮动值数据类型。理想情况下,我想限制它,使x和y必须是相同的类型。

回答

18

您需要决定是否需要该类型的存在或通用量化。通用量化,鼻翼:

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

产生,对于类型存在Num和奥德实例“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数据类型场景的数量。

另一方面,存在量化可以让你说,你根本不在乎类型是什么(更接近你实际要求的类型),代价是你不能使用任何东西对于您指定的约束条件提供的操作 - 这里很不合适。

7

这样的事情?

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

更常见的情况是,在数据声明中脱离了上下文,并在类型实际使用的位置使用“(Num a,Ord a)=> Point2 a”,但这也起作用。 – ephemient 2009-07-05 06:37:02

+0

谢谢。如果我看到它,那完美无缺,甚至有意义。 – Gregyski 2009-07-05 06:40:09