我想把这个数据类型放入一个Haskell集,但我不想给它一个Ord的一般实例。所以我想给这个集合在y-coördinate上排序,但没有实例Ord Vector。这可能吗?一组无序数据类型与给定的顺序
data Vector = V
{ x :: Double
, y :: Double
} deriving (Eq)
我想把这个数据类型放入一个Haskell集,但我不想给它一个Ord的一般实例。所以我想给这个集合在y-coördinate上排序,但没有实例Ord Vector。这可能吗?一组无序数据类型与给定的顺序
data Vector = V
{ x :: Double
, y :: Double
} deriving (Eq)
Set
要求您使用元素类型的默认Ord
实例。
如果要使用不同的Ord
例如,要做到这一点的标准方法是使用自定义的newtype
包装,然后写,一个Ord
实例:
newtype Y = Y { unY :: Vector } deriving Eq
instance Ord Y where compare = comparing ((y . unY) &&& (x . unY))
但由于比较的方式是等同于二元元组的比较方式,KennyTM的解决方案在这里最简单。
不错。我只是在输入完全相同的东西。 – jrockway 2010-03-25 09:41:45
我可以让它工作,但我不完全明白我在输入什么。所以我想我可以用(\ l - >((y.unY l),(x.unY l)))来代替&&&。但我真的不明白这是一个函数Num => b-> a(我从比较文档中得到这个签名) 你可以用较低级别的Haskell改写它吗?我在Haskell仍然是一个新手 – Ingdas 2010-03-25 11:05:26
@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
您可以将矢量转换成一个元组:
toTuple :: Vector -> (Double, Double)
toTuple (V x y) = (y, x)
fromTuple :: (Double, Double) -> Vector
fromTuple (y, x) = V x y
由于元组推导奥德(使用字典比较),它们可以被插入到设置。 (为x主要订购定义2个其他功能。)
我制作了Set
数据类型的版本,该数据类型没有Ord
上下文,但需要在构造Set
的任何地方传入类型为a -> a -> Ordering
的函数。这对你的情况有用吗?
(我不知道的版权状态,它的大部分都未经检验的文件不被修改,所以我不只是把它在这里...)
你可以把它发给我吗? ingdas(at)gmail(dot)com 这实际上正是我所需要的 – Ingdas 2010-03-26 10:04:45
-1。通过发布这样的答案,你可以帮助OP,但你不帮助整个社区。 – jfpoilpret 2010-03-26 10:35:30
好点,jfpoilpret。我将着手让它在GitHub上处于可释放状态,这样每个人都可以受益。我希望下周某个地方的ETA。 – yatima2975 2010-03-27 18:41:42
你可以存储坐标元组'(y,x)'? – kennytm 2010-03-25 08:52:41
我可以做到这一点,但那对我有什么帮助? 其实我想在不同的功能中使用不同的顺序(一次x坐标,一次y坐标),后来我想在更多维度上扩展它。 – Ingdas 2010-03-25 08:57:23