HasResolution typeclass

我刚刚抬头的HasResolution类型类,它有一个方法, resolution该声明如下:

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

我不明白上述声明中的p 。 它来自哪里,它是什么意思?


这只是一个代理。

如果你有

class HasResolution a where
  resolution :: Integer

你会大声吼叫,因为编译器无法推断你调用resolution时需要的HasResolution实例。 具体来说, resolution :: HasResolution a => Integer ,其中a出现在左侧,但不是右侧,所以你永远不能推断出a

所以,一个解决方案是

class HasResolution a where
  resolution :: a -> Integer

resolution的文件会说它并不是要检查a ; 它只是为了让编译器找出选择哪个实例。 你会用它作为resolution (undefined :: a) 。 然后出现了另一个解决方案

data Proxy a = Proxy

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

Proxy不提供resolution信息; 它的存在,再次,只为编译器推断出a的。 它比原来更好,因为该resolution实际上无法检查它的论点,所以Integer与类型有关,而与resolution的论点没有关系。 它稍差(或更好,取决于你问谁),这是更详细的resolution (Proxy :: Proxy a) (你不能只使用undefined因为实现可能在Proxy上模式匹配)。

然后这演变成了

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

这意味着,你不依赖下降到只有Proxy ,这意味着,如果你有,例如, [a]躺在范围,你可以把它传递给resolution ,而不会产生大量的冗长,同时保持代码的兼容性,仅仅使用Proxy 。 同样, resolution的第一个参数是仅供编译器使用。 这对于实际的实施没有任何意义。 您只需使用它来选择您想要的HasResolution实例。

第一个解决方案相当过时,有时候你会看到例子。 第二和第三是相当普遍的。 最近的解决方案是启用-XTypeApplications -XAllowAmbiguousTypes并且具有

class HasResolution a where
  resolution :: Integer

再次,但现在-XAllowAmbiguousTypes避开错误, -XTypeApplications允许您在调用站点指定a作为resolution @a 。 这并不经常使用,因为它不会与旧代码向后兼容,但是您仍然可以在需要新的GHC的库中看到它,并且可以承受不兼容。

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

上一篇: HasResolution typeclass

下一篇: The purpose of the Traversable typeclass