HasResolution typeclass

I just looked up the HasResolution typeclass and it has a single method, resolution that is declared as follows:

class HasResolution a where
   ...
   resolution :: p a -> Integer

I don't understand the p in the above declaration. Where does it come from and what does it mean?


It's just a proxy.

If you had

class HasResolution a where
  resolution :: Integer

you'd get yelled at because there is no way for the compiler to ever infer which instance of HasResolution you want when you call resolution . Specifically, resolution :: HasResolution a => Integer , where a appears on the left but not on the right, so you can never infer a .

So, one solution was

class HasResolution a where
  resolution :: a -> Integer

and resolution 's documentation would say that it is not meant to inspect the a ; it is just meant to let the compiler figure out which instance to pick. You'd use it as resolution (undefined :: a) . Then, another solution emerged:

data Proxy a = Proxy

class HasResolution a where
  resolution :: Proxy a -> Integer

Proxy gives no information to resolution ; it exists, again, only for the compiler to infer what a is. It's better than the original in that resolution really can't inspect its argument, so the Integer is really associated with the type and not with the argument to resolution . It's slightly worse (or better, depending on who you ask) in that usage is the more verbose resolution (Proxy :: Proxy a) (you can't just use undefined because the implementation may pattern match on Proxy ).

Then this evolved into

class HasResolution a where
  resolution :: p a -> Integer

This means that you aren't tied down to just Proxy , and it means that if you have, eg, a [a] lying in scope, you can pass it to resolution without incurring massive verbosity, while maintaining compatibility with code that just used Proxy . Again, resolution 's first argument is for the compiler's use only. It means nothing to the actual implementation. You simply use it to select the instance of HasResolution you want.

The first solution is rather dated, though you see examples sometimes. The second and third are rather common. The most recent solution is to enable -XTypeApplications -XAllowAmbiguousTypes and just have

class HasResolution a where
  resolution :: Integer

again, but now -XAllowAmbiguousTypes staves off the error and -XTypeApplications lets you specify a at the call site as resolution @a . This isn't used as often because it isn't backwards compatible with old code, but you see it more in libraries that require new GHC anyway and can afford to not have compatibility.

链接地址: http://www.djcxy.com/p/43482.html

上一篇: 如何将选项传递给ChoiceField?

下一篇: HasResolution typeclass