在Haskell中指定术语的上下文

时间:2015-11-27 13:30:20

标签: haskell ambiguous explicit-specialization

这是一个虚拟的例子:

class Test a b where
  witness :: a

f :: Test a b => a
f = witness

Haskell然后说

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的定义中删除参数Test。但是,实际上,我做不到。

我的问题是:是否存在使用行b0中明确的参数b来明确识别f :: Test a b => a的方法?

感谢。

1 个答案:

答案 0 :(得分:1)

充实Joachim Breitner's suggestion,如果您可以将其类型签名更改为witness参数或proxy b -> a,则可以使用Constant a b

这两种方法大多相同,所以这是一个偏好的问题:

{-# 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)