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