[英]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.