Haskell 类似 TypeApplication 的显式选择接口实现的方式

Haskell TypeApplication-like way of explicitly picking an implementation of an interface

我正在使用 Idris 2 v0.3。我不明白为什么编译器无法在

中找到 DistributionGaussian 的实现
interface Distribution dist where
  mean : dist -> Double

data Gaussian : Type where
  MkGaussian : Double -> Gaussian

Distribution Gaussian where
    mean (MkGaussian mean') = mean'

KnowledgeBased : Distribution d => (d : Type) -> Type

ei : KnowledgeBased Gaussian

我遇到错误

"src/Foo.idr" 12L, 459C written
Error: While processing type of ei. Can't find an implementation for Distribution ?d.

.../src/Foo.idr:12:6--12:29
    |
 12 | ei : KnowledgeBased Gaussian
    |      ^^^^^^^^^^^^^^^^^^^^^^^

你的范围是错误的;在 Distribution d => (d : Type) -> Type 中,Distribution d 部分隐式绑定 d,然后它被 d : Type 覆盖。

你想要的是:

KnowledgeBased : (d : Type) -> Distribution d => Type

这里,第一个d : Type绑定d一个Pi;它解析为 (d : Type) -> (Distribution d => Type)。所以现在 Distribution d 中的 d 是绑定的,没有自动隐式绑定。

但是,这不是惯用的 Idris。相反,您应该使用 Distribution d 绑定的隐式参数,而不用担心将其显式化的技巧:

KnowledgeBased : Distribution d => Type

ei : KnowledgeBased {d = Gaussian}