Haskell 哈斯克尔打字班速记

Haskell 哈斯克尔打字班速记,haskell,typeclass,Haskell,Typeclass,所以,我有一对类型类,我将经常一起使用,我希望避免每次都指定这两个类型。基本上,不是把 :: (Ord a, Fractional a, Ord b, Fractional b, ... Ord z, Fractional z) => 在我所有类型规格的开头,我宁愿 :: (OrdFractional a, OrdFractional b, ... OrdFractional z) 所以,我最初的想法是声明一个新的typeclass module Example where clas

所以,我有一对类型类,我将经常一起使用,我希望避免每次都指定这两个类型。基本上,不是把

:: (Ord a, Fractional a, Ord b, Fractional b, ... Ord z, Fractional z) =>
在我所有类型规格的开头,我宁愿

:: (OrdFractional a, OrdFractional b, ... OrdFractional z)
所以,我最初的想法是声明一个新的typeclass

module Example where

class (Fractional a, Ord a) => OrdFractional a

example :: (OrdFractional a, OrdFractional b) => (a,b) -> (a,b) -> (a,b) -> Bool
example (x1,y1) (x2,y2) (x3,y3) = (x1/x2 < x2/x3) && (y1/y2 < y2/y3)

有什么方法可以做到这一点吗?

您需要的是类别名。有人建议将其添加到Haskell的中,当编译器说“
使用-XFlexibleInstances
”时,您应该尝试添加

{-# LANGUAGE FlexibleInstances #-}
到源代码的顶部(当然,阅读文档了解它的功能!)

在这种特定情况下,这将使您的代码正常工作:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
需要灵活的实例才能在实例头上启用
=>
上下文,并且需要不可判定的实例,因为编译器在处理
上下文时,可以结束在上下文中添加
分数a
Ord a
——这对最终确定
a
没有直接帮助,在适当的可怕情况下,类型检查可能会出现分歧;编译器真的不喜欢这样。(如果编译器永远运行或内存不足,您可能也不会喜欢它。)

您的超类解决方案暗示其他类最接近您在Haskell中所希望的。尽管这需要新类的手动实例,但它有时也会被使用,例如在库中


正如CesarB所提到的,类别名可以做您想要做的事情(以及更多),但它们只是一个已经存在多年且从未实施过的建议,可能是因为它存在许多问题。相反,出现了各种其他提案,但也没有一项得到实施。(有关这些建议的列表,请参见此。)的一个项目是修改GHC,使其包含一小部分名为上下文同义词的类别名(它完全满足您在此处的要求,仅此而已),但遗憾的是,它从未完成。

随着GHC 7.4中引入的ConstraintKinds扩展,约束现在是类型
约束
,因此您可以使用普通类型同义词来获得所需的:

{-# LANGUAGE ConstraintKinds #-}

type OrdFractional a = (Ord a, Fractional a)

新的ConstraintKinds扩展应该允许上下文同义词。
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}

type OrdFractional a = (Ord a, Fractional a)