Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  [Haskell-cafe] Multi-parameter type classes and
      ambiguous type variables... (Stuart Hungerford)


----------------------------------------------------------------------

Message: 1
Date: Sun, 22 Mar 2015 07:15:52 +1100
From: Stuart Hungerford <[email protected]>
To: Chris Wong <[email protected]>
Cc: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>,
        Haskell-cafe Cafe <[email protected]>
Subject: Re: [Haskell-beginners] [Haskell-cafe] Multi-parameter type
        classes and ambiguous type variables...
Message-ID:
        <cag+kmrhr6vtuvjcmvk+pzxda8mha-h0apaw8wmh8hgkgpml...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

On Sat, Mar 21, 2015 at 7:31 PM, Chris Wong <[email protected]> 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


------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 81, Issue 52
*****************************************

Reply via email to