在Haskell数据类型中输入类 [英] Type classes in Haskell data types

查看:120
本文介绍了在Haskell数据类型中输入类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  data Point1 = Point1 {
x ::整数
,y ::整数
}

数据类型中的变量?如果是这样如何?我意识到可以将它作为代数数据类型来完成,并为每种类型的点定义不同的数据类型,但是我想知道是否有办法以更紧凑和更灵活的方式实现此目的。



例如

使用函数声明语法的伪代码

b $ bx ::(Num a,Ord a)=> a
,y ::(Num a,Ord a)=> a
}

目标是允许一个人存储 Int Integer Float Double 值。理想情况下,我想限制它,使x和y必须是相同的类型。 你需要决定如果你想要这种类型的存在或普遍量化。通用量化,ala:

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

产生一个证明义务,Num和Ord实例存在类型'a'但实际上并没有什么帮助,因为它只是通过构建该类型的值或者当模式匹配它时使用Point类来给你一个义务。



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

 数据Point2 a = Point2 aa推导(Eq ,Ord,Show,Read)

并且让你的每个实例都依赖于你想要的额外信息。

 实例Num a => Num(Point2 a)其中
...

实例(Num a,Ord a)=> SomeClass(Point2 a)其中
...

这让你传递并构造更少多余的字典,并增加了可以使用Point2数据类型的场景的数量。另一方面,存在量化可以让你说你不关心什么该类型完全(接近你实际请求的类型),代价是除了你指定的约束条件提供的操作之外,你不能使用任何东西 - 这里很不合适。


In Haskell, one can define a data type like so:

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

Can one use type classes for variables inside a data type? If so how? I realize it is possible to do this as an algebraic data type, with a different definition for each kind of point, but I'm wondering if there's a way to accomplish this in a more compact and flexible manner.

e.g. Something along the lines of this pseudocode which uses function declaration syntax:

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

The goal would be to allow one to store Int, Integer, Float or Double values in the data type. Ideally, I'd like to restrict it so that x and y must be of the same type.

解决方案

You need to decide if you want an existential or universal quantification on that type. Universal quantification, ala:

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

yields a proof obligation that Num and Ord instances exist for the type 'a' but doesn't actually help all that much, because all it does is give you an obligation when you go to use the Point class by constructing a value of that type or when you go to pattern match it.

In almost all cases you are better off defining

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

and making each of your instances contingent on the extra information you want.

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

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

This lets you pass around and construct fewer superfluous dictionaries and increases the number of scenarios in which your Point2 data type can be used.

On the other hand existential quantification can let you say that you don't care what the type is at all (closer to what you actually requested, type wise) at the expense that you can't use anything on it except for the operations provided by the constraints you specified -- a pretty poor fit here.

这篇关于在Haskell数据类型中输入类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆