2

Here is a dummy example:

class Test a b where
  witness :: a

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

Haskell then say

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

Error comes from the fact that Haskell cannot infer type variable b0 and a solution would be to remove parameter b from definition of the typeclass Test. But, in reality, I cannot.

My question is : Does it exist a way to explicity identify b0 with explicit parameter b given in line f :: Test a b => a?

Thanks.

abitbol
  • 487
  • 4
  • 8

1 Answers1

1

Fleshing out Joachim Breitner's suggestion, you could use witness if you can alter its type signature to be proxy b -> a argument or Constant a b.

The two approaches are mostly equivalent, so it's a matter of preference:

{-# 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)
Community
  • 1
  • 1
rampion
  • 87,131
  • 49
  • 199
  • 315
  • Thank you all! But what Constant and proxy type constructors are for? – abitbol Dec 03 '15 at 16:00
  • They bring the `b` type into scope, so the compiler knows which instance of `Test a b` to use. If only `a` is in scope, it has no way of determining which instance to use, since there may be `Test a b` instances for multiple different `b`s, given an `a`. – rampion Dec 03 '15 at 17:52