类型类
Data. Bits
有一个方法 isSigned :: a -> Bool
,如果参数的类型是有符号类型,则返回 True
。文档明确指出该参数被忽略。类型类中还有其他类似的方法;还有其他类型类也具有此类方法。我的问题:为什么选择这样的设计?该值仅取决于类型,所以为什么不直接:
isSigned :: Bool
作为后续:假设我有一个带有无效方法的自定义类型类
method :: Bool
。有什么理由改变它并像Data.Bits
那样做,即method :: a -> Bool
?
简而言之,参数在运行时被忽略,但在编译期间使用参数的类型来选择要在运行时使用的正确的isSigned
实例。
isSigned :: Bool
之类的值。
> class Foo a where isSigned :: Bool
<interactive>:1:19: error:
• Could not deduce (Foo a0)
from the context: Foo a
bound by the type signature for:
isSigned :: forall a. Foo a => Bool
at <interactive>:1:19-34
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘isSigned’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method: isSigned :: forall a. Foo a => Bool
In the class declaration for ‘Foo’
如果启用 TypeApplications
和 AllowAmbiguousTypes
扩展,您可以执行以下操作:
class Foo a where
isSigned :: Bool
instance Foo Int where
isSigned = True
instance Foo Char where
isSigned = False
单独使用 isSigned
仍然会出现错误,但您可以使用 isSigned @Int
或
isSigned @Char
来获取给定类型的特定值。
回到标准 Haskell,我们需要某种方法来选择需要哪个实例的
isSigned
值,我们通过定义一个函数来实现这一点,该函数的参数类型将其与特定实例联系起来。参数的 value
被忽略,但在类型检查和编译期间使用type 来选择正确的实例。