The benefit of this could be to store certain metadata about the type in a canonical location. Sometimes, it isn't convenient to have a value of the type before using some instance methods on it; For instance if I have:
class Foo a where foo :: String foo = "Foo"
This is not actually valid Haskell. Instead it seems I have to have something like:
class Foo a where foo :: a -> String foo = const "Foo"
foo will actually have type
Foo a => a -> String, but I would actually like to be able to do something like having a
foo with type
Instance Foo -> String. For this to be useful in some contexts, it might be also necessary to iterate over all (in-scope?) instances, or in other contexts, to be able to specifically materialize an instance for a given type.
I guess the issue is that instances and typeclasses are not first-class entities in Haskell?
The "old school" way of doing it is providing a "dummy" parameter whose purpose is nothing but helping the compiler find the appropriate instance. In this world, your class would look something like:
data Dummy a = Dummy class Foo a where foo :: Dummy a -> String -- usage: boolFoo = foo (Dummy :: Dummy Bool)
In fact, this trick was so ubiquitous that the
Dummy type was semi-standardized as
But in modern GHC there is a better way:
With this extension enabled, you can just straight up specify the type when calling the class method:
class Foo a where foo :: String boolFoo = foo @Bool
(this doesn't only work for class methods; it will work with any generic function, but be careful with the order of type parameters!)
You may also need to enable
AllowAmbiguousTypes in order to declare such class. Though I'm not sure I remember this correctly, and I don't have a computer handy to check.