所以我在玩 Haskell 并注意到一些让我困惑的事情。我定义了一个复杂的浮点数据结构,并想在它上面使用比较运算符。最初我这样做了,效果很好:
data Cplx = Cplx Float Float deriving (Eq, Show)
instance Ord Cplx where
(<=) a b = (<=) (normCplx a) (normCplx b)
(>=) a b = (>=) (normCplx a) (normCplx b)
(<) a b = (<) (normCplx a) (normCplx b)
(>) a b = (>) (normCplx a) (normCplx b)
normCplx :: Cplx -> Float
normCplx (Cplx a1 a2) = sqrt( a1^2 + a2^2)
Run Code Online (Sandbox Code Playgroud)
但我也注意到刚刚声明:
data Cplx = Cplx Float Float deriving (Eq, Show)
instance Ord Cplx where
(<=) a b = (<=) (normCplx a) (normCplx b)
normCplx :: Cplx -> Float
normCplx (Cplx a1 a2) = sqrt( a1^2 + a2^2)
Run Code Online (Sandbox Code Playgroud)
也很好地完成了工作。Haskell 如何推断其他比较运算符的定义,仅给出单个定义?
谢谢!
其余部分仅使用(<=)(或compare)使用类型类实现- 这是此处文档中的“最小实现”:http : //hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html #t:顺序平均。
最小完整定义:比较或 <=。对于复杂类型,使用比较可以更有效。
遗憾的是,在这种情况下,您无法直接从 Hackage 显示源代码,但正如Ord a所暗示Eq a的那样,不难想象这是如何完成的。
例如,你已经(<=)实施(<)可以只是:
a < b = a /= b && a <= b
Run Code Online (Sandbox Code Playgroud)
你得到
a >= b = not (a < b)
Run Code Online (Sandbox Code Playgroud)
最后
a > b = not (a <= b)
Run Code Online (Sandbox Code Playgroud)
或类似的东西。
顺便说一句,正如您在第一个实现中看到的那样compare,您没有实现,max或者min即使它是类型类的一部分,并且它也被推断出来了。
或许你可以试着自己猜一猜。
大卫找到了来源 - 这是从那里开始的实施:
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
x <= y = case compare x y of { GT -> False; _ -> True }
x > y = case compare x y of { GT -> True; _ -> False }
x >= y = case compare x y of { LT -> False; _ -> True }
-- These two default methods use '<=' rather than 'compare'
-- because the latter is often more expensive
max x y = if x <= y then y else x
min x y = if x <= y then x else y
{-# MINIMAL compare | (<=) #-}
Run Code Online (Sandbox Code Playgroud)
如您所见:如果您有compare或(<=)其他所有内容如下。
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |