[Haskell-cafe] More newbie typeclass confusion...

Jonathan Cast jonathanccast at fastmail.fm
Sat Dec 29 22:43:32 EST 2007


On 29 Dec 2007, at 9:31 PM, alex wrote:

> Hi there.
>
> If someone can tell me why I am getting type ambiguity
> in the following code:
>
>     class (Ord s, Num s) => Scalar s where
>         zero :: s
>
>     class Metric m where
>         delta   :: Scalar s => m -> m -> s
>
>         (=~)    :: m -> m -> Bool
>         (/~)    :: m -> m -> Bool
>
>         (=~) a b    = (delta a b) <= zero
>         (/~) a b    = not (a =~ b)
>
> I will scream.
>
> The error I get compiling is:
>
>     Ambiguous type variable `s' in the constraint:
>       `Scalar s' arising from a use of `delta' at
> test.hs:13:23-31
>     Probable fix: add a type signature that fixes
> these type variable(s)
>
> If I change "Scalar" to "Num", and "zero" to "0"
> within the class "Metric", then it works.
>
> I don't get it. "zero" is defined in the "Scalar"
> class, and "delta" returns a Scalar, and Scalar
> derives "Ord", so where's the ambiguity?

delta is polymorphic in s; that is, it works for any value of type s  
in the class Scalar, and has some definition that (presumably) uses  
the value zero.  (And I assume other methods of Scalar).  Its value  
is thus some arbitrary function of the methods of Scalar (and its  
super classes); to call it, you need a specific type so the function  
can be supplied with the methods to use.

The code is still ambiguous if you switch to Num, but since newcomers  
to Haskell are frequently confused by Haskell's approach to numeric  
computations, Haskell 98 has a solution for this case; ambiguous type  
variables which are constrained to be instances of Num get  
`defaulted' to particular numeric types.  So the ambiguity goes away.

jcc



More information about the Haskell-Cafe mailing list