这样做的好处是可以将有关类型的某些元数据存储在规范位置。有时,在使用某些实例方法之前先拥有该类型的值并不方便;例如,如果我有:
class Foo a where
foo :: String
foo = "Foo"
这实际上不是有效的 Haskell。相反,我似乎必须有类似的东西:
class Foo a where
foo :: a -> String
foo = const "Foo"
现在 foo
实际上将具有 Foo a => a -> String
类型,但实际上我希望能够做一些事情,比如拥有一个 foo
类型为 Instance Foo -> String
。为了使其在某些上下文中有用,可能还需要遍历所有(范围内?)实例,或者在其他上下文中,以便能够具体化给定类型的实例。
我想问题是实例和类型类不是 Haskell 中的一流实体?
最佳答案
“老派”的做法是提供一个“虚拟”参数,其目的只是帮助编译器找到合适的实例。在这个世界上,您的类(class)看起来像这样:
data Dummy a = Dummy
class Foo a where
foo :: Dummy a -> String
-- usage:
boolFoo = foo (Dummy :: Dummy Bool)
事实上,这个技巧非常普遍,以至于 Dummy
类型被半标准化为 Data.Proxy
.
但是在现代 GHC 中有一个更好的方法:TypeApplications
。
启用此扩展后,您可以在调用类方法时直接指定类型:
class Foo a where
foo :: String
boolFoo = foo @Bool
(这不仅适用于类方法;它适用于任何泛型函数,但要注意类型参数的顺序!)
您可能还需要启用 AllowAmbiguousTypes
才能声明此类。虽然我不确定自己是否记错了,而且我手边没有电脑可以查。
关于haskell - 有没有办法直接引用 Haskell 中的类型类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54934778/