Haskell:Typeclass意味着其他Typeclass

Haskell:Typeclass意味着其他Typeclass,haskell,Haskell,在Haskell中有可能让一个typeclass暗示另一个typeclass吗?例如,假设有一堆“东西”可以按“属性”排序: 由于多种原因,这显然不起作用。我想知道这是否可能?您可以这样做: instance Ord Person where compare p1 p2 = compare (age p1) (age p2) 现在,标准的正如您所指定的那样,OrdByKey类只能有一个实例 每种类型,当听起来您希望能够声明实例时 对于记录类型中的每个字段 要实现这一点,您必须将字段类型

在Haskell中有可能让一个typeclass暗示另一个typeclass吗?例如,假设有一堆“东西”可以按“属性”排序:

由于多种原因,这显然不起作用。我想知道这是否可能?

您可以这样做:

instance Ord Person where
    compare p1 p2 = compare (age p1) (age p2)

现在,标准的
正如您所指定的那样,
OrdByKey
类只能有一个实例 每种类型,当听起来您希望能够声明实例时 对于记录类型中的每个字段

要实现这一点,您必须将字段类型放入类中 定义也一样。这使您可以执行以下操作:

{-# LANGUAGE MultiParamTypeClasses #-}

data Person = Person { name :: String, age :: Int }

class (Ord r) => OrdByKey o r where
   orderKey :: o -> r

instance OrdByKey Person Int where
  orderKey p = age p

x <=? y = (orderKey x :: Int) <= (orderKey y :: Int)
您将无法在
名称
ssn
字段。您可以通过将每个字段包装成一个
newtype
因此每个字段都有一个唯一的类型。所以你的
类型看起来 像

这将导致大量的
newtype
浮动

这样做的真正缺点是需要为
orderKey
函数。我建议使用
Data.Function
编写适当的比较函数。我想 函数式

compareByKey :: (Ord b) => (a -> b) -> a -> a -> Bool
compareByKey = on (<=)
compareByKey::(Ord b)=>(a->b)->a->a->Bool

compareByKey=on(如果您的目标只是根据记录中的特定字段排序,那么您可以为
Person
定义
Ord
的实例来比较该特定字段。@sabauma是的,但我正在寻找“可以通过某个键进行比较”的泛化对于这个特殊的例子,看看函数:
comparing age you me
作为一个更通用的操作符,然后可以看看
comparing
。它的类型是
(b->b->c)->(a->b)->a->a->c
,所以
comparing age=on comparing age
,但是你也可以在(=)上设置
f
在应用
f
后测试两件事情是否相等。看起来使用多参数类型类是一种干净的方法。谢谢!
instance Ord Person where
    compare p1 p2 = compare (age p1) (age p2)
{-# LANGUAGE MultiParamTypeClasses #-}

data Person = Person { name :: String, age :: Int }

class (Ord r) => OrdByKey o r where
   orderKey :: o -> r

instance OrdByKey Person Int where
  orderKey p = age p

x <=? y = (orderKey x :: Int) <= (orderKey y :: Int)
data Person = Person { name :: String, age :: Int, ssn :: String}
data Person = Person { name :: Name, age :: Age, ssn :: SSN}
compareByKey :: (Ord b) => (a -> b) -> a -> a -> Bool
compareByKey = on (<=)