Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 自定义Ord实例挂起在列表上_Haskell_Typeclass - Fatal编程技术网

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