简体   繁体   English

HasResolution类型类

[英]HasResolution typeclass

I just looked up the HasResolution typeclass and it has a single method, resolution that is declared as follows: 我只是查找了HasResolution 类型类 ,它有一个方法, resolution声明如下:

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

I don't understand the p in the above declaration. 我不明白上述声明中的p 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 . 你会在,因为没有办法让编译器永远推断其中的情况下获得骂得HasResolution你想,当你调用resolution Specifically, resolution :: HasResolution a => Integer , where a appears on the left but not on the right, so you can never infer a . 具体来说, resolution :: HasResolution a => Integer ,其中a出现在左边但不在右边,所以你永远不能推断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 ; resolution的文件会说它不是要检查a ; it is just meant to let the compiler figure out which instance to pick. 它只是让编译器找出要选择的实例。 You'd use it as resolution (undefined :: a) . 你将它用作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 ; Proxy不提供resolution信息; it exists, again, only for the compiler to infer what a is. 它再次存在,仅用于编译器推断出a是什么。 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 . 它比原始resolution更好,因为resolution 实际上无法检查它的参数,因此Integer实际上与类型相关联,而不是与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 ). 它稍差(或更好,取决于你问的是谁),因为用法是更冗长的resolution (Proxy :: Proxy a) (你不能只使用undefined因为实现可能在Proxy上模式匹配)。

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 . 这意味着您不仅仅局限于Proxy ,这意味着如果您有例如[a]在范围内,您可以将其传递给resolution而不会产生大量冗长,同时保持与刚刚使用的代码的兼容性Proxy Again, resolution 's first argument is for the compiler's use only. 同样, resolution的第一个参数仅供编译器使用。 It means nothing to the actual implementation. 它对实际实现没有任何意义。 You simply use it to select the instance of HasResolution you want. 您只需使用它来选择所需的HasResolution实例。

Proxy eventually became so common that GHC.Exts got a new member: Proxy# . Proxy最终变得如此普遍, GHC.Exts得到了一个新成员: Proxy# Proxy# has no runtime representation, so it incurs no performance penalty, unlike Proxy (or the above polymorphic p trick). Proxy#没有运行时表示,因此与Proxy (或上述多态p技巧)不同,它不会造成性能损失。 Proxy# , however, suffers from the fact that its kind is forall k. k -> TYPE (TupleRep '[]) 然而, Proxy#受到这样的事实的影响,即它的类型是forall k. k -> TYPE (TupleRep '[]) forall k. k -> TYPE (TupleRep '[]) . forall k. k -> TYPE (TupleRep '[]) By not living in * like all the other "well-behaved" types, it cannot participate in the polymorphic p trick. 如果不居住在*像所有其他的“乖巧”的类型,它不能参与多态p伎俩。

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

The first solution is rather dated, though you see examples sometimes. 第一个解决方案是相当过时的,尽管你有时会看到例子。 The second and third are rather common, and the fourth was superseded pretty quickly by the most recent solution, which is to enable -XTypeApplications -XAllowAmbiguousTypes and just have 第二个和第三个相当常见,第四个被最新的解决方案很快取代,即启用-XTypeApplications -XAllowAmbiguousTypes并且只有

class HasResolution a where
  resolution :: Integer

again. 再次。 -XAllowAmbiguousTypes staves off the error and -XTypeApplications lets you specify a at the call site as resolution @a . -XAllowAmbiguousTypes消除错误, -XTypeApplications允许您在呼叫站点指定a作为resolution @a This can't be used in code that needs to be a certain degree of backwards compatible, but you see it more in libraries that require new GHC anyway and can afford to not have compatibility. 这不能用在需要一定程度向后兼容的代码中,但是在需要新GHC的库中你会看到更多,并且可以承受不具备兼容性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM