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

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to