本文介绍了HasResolution类型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是查找了HasResolution typeclass ,它具有单个方法resolution,该方法声明如下:

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

我不理解上述声明中的p.它来自哪里,意味着什么?

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

推荐答案

它只是一个代理.

如果有

class HasResolution a where
  resolution :: Integer

您会大吼大叫,因为编译器无法在调用resolution时推断出您想要的HasResolution的哪个实例.具体来说,是resolution :: HasResolution a => Integer,其中a出现在左侧,而不是出现在右侧,因此您永远无法推断a.

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.

所以,一种解决方法是

class HasResolution a where
  resolution :: a -> Integer

resolution的文档会说,这并不是要检查a.这只是为了让编译器找出要选择的实例.您可以将其用作resolution (undefined :: a).然后,出现了另一种解决方案:

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不提供任何信息给resolution;同样,它仅存在于编译器推断a是什么的情况下.它比原始版本更好,因为resolution 确实无法检查其参数,因此Integer确实与类型关联,而不与resolution的参数关联. resolution (Proxy :: Proxy a)较为冗长(因为不能在Proxy上实现模式匹配,所以不能仅仅使用undefined),因此用法稍差一点(或更好,具体取决于您询问的人).

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).

这演变成

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

这意味着您不仅仅局限于Proxy,这意味着,如果您将例如[a]放在范围内,则可以将其传递给resolution而不会引起大量的冗长,而保持与刚刚使用Proxy的代码的兼容性.同样,resolution的第一个参数仅供编译器使用.这对于实际的实现没有任何意义.您只需使用它来选择所需的HasResolution的实例.

This means that you aren't tied down to just Proxy, and it means that if you have, e.g., 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.

Proxy最终变得如此普遍,以至GHC.Exts有了一个新成员: Proxy# . Proxy#没有运行时表示形式,因此与Proxy(或上述多态的p技巧)不同,它不会造成性能损失.但是,Proxy#受其类型为forall k. k -> TYPE (TupleRep '[])的困扰.通过不像其他所有行为良好"的类型一样生活在*中,它就不能参与多态的p技巧.

Proxy eventually became so common that GHC.Exts got a new member: Proxy#. Proxy# has no runtime representation, so it incurs no performance penalty, unlike Proxy (or the above polymorphic p trick). Proxy#, however, suffers from the fact that its kind is forall k. k -> TYPE (TupleRep '[]). By not living in * like all the other "well-behaved" types, it cannot participate in the polymorphic p trick.

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

第一个解决方案是过时的,尽管有时会看到一些示例.第二个和第三个很常见,第四个被最新的解决方案很快取代,最新的解决方案是启用-XTypeApplications -XAllowAmbiguousTypes并拥有

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

class HasResolution a where
  resolution :: Integer

再次

. -XAllowAmbiguousTypes避免错误,并且-XTypeApplications允许您在呼叫站点将a指定为resolution @a.不能在需要一定程度向后兼容的代码中使用它,但是在需要新GHC并且负担不起兼容性的库中,您会发现更多.

again. -XAllowAmbiguousTypes staves off the error and -XTypeApplications lets you specify a at the call site as 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.

这篇关于HasResolution类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 20:24