2010-03-25 58 views
3

我想把这个数据类型放入一个Haskell集,但我不想给它一个Ord的一般实例。所以我想给这个集合在y-coördinate上排序,但没有实例Ord Vector。这可能吗?一组无序数据类型与给定的顺序

data Vector = V 
    { x :: Double 
    , y :: Double 
    } deriving (Eq) 
+0

你可以存储坐标元组'(y,x)'? – kennytm 2010-03-25 08:52:41

+0

我可以做到这一点,但那对我有什么帮助? 其实我想在不同的功能中使用不同的顺序(一次x坐标,一次y坐标),后来我想在更多维度上扩展它。 – Ingdas 2010-03-25 08:57:23

回答

8

Set要求您使用元素类型的默认Ord实例。

如果要使用不同的Ord例如,要做到这一点的标准方法是使用自定义的newtype包装,然后写,一个Ord实例:

newtype Y = Y { unY :: Vector } deriving Eq 
instance Ord Y where compare = comparing ((y . unY) &&& (x . unY)) 

但由于比较的方式是等同于二元元组的比较方式,KennyTM的解决方案在这里最简单。

+2

不错。我只是在输入完全相同的东西。 – jrockway 2010-03-25 09:41:45

+1

我可以让它工作,但我不完全明白我在输入什么。所以我想我可以用(\ l - >((y.unY l),(x.unY l)))来代替&&&。但我真的不明白这是一个函数Num => b-> a(我从比较文档中得到这个签名) 你可以用较低级别的Haskell改写它吗?我在Haskell仍然是一个新手 – Ingdas 2010-03-25 11:05:26

+0

@ngdas:你在哪里得到'Num'? '比较'的签名是'Ord a =>(b - > a) - > b - > b - > Ordering'(http://hackage.haskell.org/packages/archive/base/latest/doc/html /Data-Ord.html#v:comparing) – kennytm 2010-03-25 11:40:36

4

您可以将矢量转换成一个元组:

toTuple :: Vector -> (Double, Double) 
toTuple (V x y) = (y, x) 

fromTuple :: (Double, Double) -> Vector 
fromTuple (y, x) = V x y 

由于元组推导奥德(使用字典比较),它们可以被插入到设置。 (为x主要订购定义2个其他功能。)

0

我制作了Set数据类型的版本,该数据类型没有Ord上下文,但需要在构造Set的任何地方传入类型为a -> a -> Ordering的函数。这对你的情况有用吗?

(我不知道的版权状态,它的大部分都未经检验的文件不被修改,所以我不只是把它在这里...)

+0

你可以把它发给我吗? ingdas(at)gmail(dot)com 这实际上正是我所需要的 – Ingdas 2010-03-26 10:04:45

+0

-1。通过发布这样的答案,你可以帮助OP,但你不帮助整个社区。 – jfpoilpret 2010-03-26 10:35:30

+0

好点,jfpoilpret。我将着手让它在GitHub上处于可释放状态,这样每个人都可以受益。我希望下周某个地方的ETA。 – yatima2975 2010-03-27 18:41:42