指定Haskell中术语来源的上下文

指定Haskell中术语来源的上下文,haskell,ambiguous,explicit-specialization,Haskell,Ambiguous,Explicit Specialization,下面是一个虚拟示例: class Test a b where witness :: a f :: Test a b => a f = witness 哈斯克尔接着说 Could not deduce (Test a b0) arising from a use of ‘witness’ from the context (Test a b) bound by the type signature for f :: Test a b => a at test.hs:8

下面是一个虚拟示例:

class Test a b where
  witness :: a

f :: Test a b => a
f = witness
哈斯克尔接着说

Could not deduce (Test a b0) arising from a use of ‘witness’
from the context (Test a b)
  bound by the type signature for f :: Test a b => a
  at test.hs:8:6-18
The type variable ‘b0’ is ambiguous
Relevant bindings include f :: a (bound at test.hs:9:1)
In the expression: witness
In an equation for ‘f’: f = witness
错误源于Haskell无法推断类型变量
b0
,解决方案是从类型类
测试的定义中删除参数
b
。但事实上,我不能

我的问题是:是否存在一种方法,可以通过第
f::testab=>a
行中给出的显式参数
b
来明确识别
b0

谢谢。

如果可以将其类型签名更改为
代理b->a
参数或
常量a b
,则可以使用
witness

这两种方法基本上是等效的,因此这是一个偏好问题:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module SO33958506 where

import Data.Functor.Constant
import Data.Proxy

class Test a b where
  constantWitness :: Constant a b
  proxyWitness :: proxy b -> a

constantWitnessWithProxy :: forall proxy a b. Test a b => proxy b -> a
constantWitnessWithProxy _ = getConstant $ (constantWitness :: Constant a b)

proxyWitnessAsConstant :: forall a b. Test a b => Constant a b
proxyWitnessAsConstant = Constant $ proxyWitness (Proxy :: Proxy b)

witness
添加
Proxy b
参数(甚至
Proxy b
)是一个选项吗?或者,添加函数依赖项
a->b
是一个选项吗?或者将其更改为
witness::Constant a b
谢谢大家!但是常量和代理类型构造函数是用于什么的呢?它们将
b
类型带入范围,因此编译器知道使用
testab
的哪个实例。如果只有
a
在范围内,则无法确定要使用哪个实例,因为在给定
a
的情况下,可能存在针对多个不同
b
测试ab
实例。