Haskell 自定义Ord实例挂起在列表上
这是从我的代码中摘录的,缩减到主要大小。让我们试着比较一下:Haskell 自定义Ord实例挂起在列表上,haskell,typeclass,Haskell,Typeclass,这是从我的代码中摘录的,缩减到主要大小。让我们试着比较一下: import Data.Function (on) import Data.List (sort) data Monomial = Monomial { m_coeff :: Coefficient , m_powers :: [(Variable, Power)] } deriving () instance Ord Monomial where (>=) = on (>=
import Data.Function (on)
import Data.List (sort)
data Monomial = Monomial
{ m_coeff :: Coefficient
, m_powers :: [(Variable, Power)]
}
deriving ()
instance Ord Monomial where
(>=) = on (>=) m_powers
instance Eq Monomial where
(==) = on (==) m_powers
尽管标准规定Eq实例
的最小声明为$compare$
或$(>=)$
这里可能有什么问题?列表中的(>=)似乎工作正常。简短回答:
您需要提供
(=)
详细解释:Haskell中的类型类通常会使用其他方法实现某些方法的默认实现。然后,您可以选择要实现哪些。例如,
Eq
如下所示:
*Main> (Monomial 1 [("x",2)]) > (Monomial (-1) [])
True
*Main> (Monomial 1 [("x",2)]) < (Monomial (-1) [])
/* Computation hangs here */
在这里,您必须实现(==)
或(/=)
,否则尝试使用其中任何一个都将导致无限循环。您需要提供的方法通常列为文档中的最小完整定义
Ord
实例的最小完整定义是(让我们看看Ord
的默认实例:
instance Ord Monomial where
compare = compare `on` m_powers
class(等式a)=>Ord a,其中
比较::a->a->排序
(=)::a->a->Bool
最大值,最小值::a->a->a
比较x y=如果x==y,则等式
--注意:必须是“=”。类型变量=字符串
,对吗?如果定义比较
而不是(>=)
,会发生什么?它确实有效。谢谢。在实例Ord单项式
的正下方有一个实例Eq单项式
,我定义了(=)这里。@FrancisDrake:是的,我只是用了Eq
作为例子,因为它更简单。阅读我的其余答案。你已经搞定了,但它隐藏在许多不必要的绒毛之间。答案很简单:“Ord的最小完整定义是=
”。我不认为关于“最小完整定义”的意义有这么大的讲座这是需要的。
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
instance Ord Monomial where
compare = compare `on` m_powers
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