[Haskell-cafe] [Haskell-beginners] Multi-parameter type classes and ambiguous type variables...

Stuart Hungerford stuart.hungerford at gmail.com
Sat Mar 21 20:15:52 UTC 2015


On Sat, Mar 21, 2015 at 7:31 PM, Chris Wong <lambda.fairy at gmail.com> wrote:

> [...]
>>> check :: (Eq g, M r g) => g -> Bool
>>> check x = sca one x == x
>>>
>>> The problem I have is that GHC is finding the "r" type variable in the
>>> "check" function ambiguous. Given my still limited Haskell knowledge
>>> I'm not surprised this is happening. What I would like to know is how
>>> experienced Haskellers handle this situation in practice: is there an
>>> idiomatic way of disambiguating "r" or is it a sign of poor type class
>>> design?
>
> In the type signature:
>
>     check :: (Eq g, M r g) => g -> Bool
>
> you fix the type `g`, but not the type `r`. This causes an ambiguity
> in the program because if you had e.g.
>
>     instance M Float Vector where ...
>     instance M Int Vector where ...
>
> both in the same program, and you passed a Vector to `check`, GHC
> won't know which instance to choose.
>
> To solve this ambiguity, either fix `r` with an extra parameter:
>
>     check :: (Eq g, M r g) => r -> g -> Bool
>     check one' x = sca one' x == x
>
> Or declare that `r` is uniquely determined by `g` using a *functional
> dependency*:
>
>     class (R r, AG g) => M r g | g -> r where
>         sca :: r -> g -> g
>
> Or equivalently, using *associated types*:
>
>     class (AG g, R (Scalar g)) => M g where
>         type Scalar g :: *
>         sca :: Scalar g -> g -> g
>
>     check :: (Eq g, M g) => g -> Bool
>     check x = -- as before
>
> A Google search for these two terms should yield plenty of tutorials
> and examples.

Thanks for this excellent explanation.

> (By the way, I'd suggest using longer names like "Ring" and
> "AdditiveGroup" instead, as they're easier to read.)

Yes -- I stripped the example down, including the full names of the
type classes, for explaining the issue. I could well have left the
full names though.


Stu


More information about the Haskell-Cafe mailing list