[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