HasResolution类型类

mel*_*ton 7 haskell

我只是查找了HasResolution 类型类,它有一个方法,resolution声明如下:

class HasResolution a where
   ...
   resolution :: p a -> Integer
Run Code Online (Sandbox Code Playgroud)

我不明白p上面的声明.它来自哪里,它意味着什么?

HTN*_*TNW 13

这只是一个代理人.

如果你有

class HasResolution a where
  resolution :: Integer
Run Code Online (Sandbox Code Playgroud)

你会在,因为没有办法让编译器推断有史以来获得大喊其中的情况下HasResolution,你想,当你调用resolution.具体来说,resolution :: HasResolution a => Integer其中a左侧,但没有出现在右边,所以你永远无法推断a.

所以,一个解决方案是

class HasResolution a where
  resolution :: a -> Integer
Run Code Online (Sandbox Code Playgroud)

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

data Proxy a = Proxy

class HasResolution a where
  resolution :: Proxy a -> Integer
Run Code Online (Sandbox Code Playgroud)

Proxy没有提供任何信息resolution; 它再次存在,仅用于编译器推断出是什么a.它比原始的更好,因为它resolution 真的无法检查它的参数,因此Integer它实际上与类型相关联而不是与参数相关联resolution.它的情况稍差(或更好,取决于你问的是谁),因为用法更冗长resolution (Proxy :: Proxy a)(你不能只使用undefined因为实现可能模式匹配Proxy).

这演变成了

class HasResolution a where
  resolution :: p a -> Integer
Run Code Online (Sandbox Code Playgroud)

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

Proxy最终变得如此普遍以至于GHC.Exts得到了新成员:Proxy#.Proxy#没有运行时表示,因此它不会产生性能损失,不像Proxy(或上面的多态p技巧).Proxy#但是,它的种类是这样的forall k. k -> TYPE (TupleRep '[]).由于*不像所有其他"表现良好"的类型一样生活,它不能参与多态p技巧.

class HasResolution a where
  resolution :: Proxy# a -> Integer
Run Code Online (Sandbox Code Playgroud)

第一个解决方案相当过时,尽管有时会看到示例.第二个和第三个是相当普遍的,第四个被最新的解决方案很快取代,这个解决方案是启用-XTypeApplications -XAllowAmbiguousTypes并且只有

class HasResolution a where
  resolution :: Integer
Run Code Online (Sandbox Code Playgroud)

再次.-XAllowAmbiguousTypes避开错误并-XTypeApplications允许您a在呼叫站点指定为resolution @a.这不能用在需要一定程度向后兼容的代码中,但是在需要新GHC的库中你会看到更多,并且可以承受不具备兼容性.