[Haskell-cafe] Re: New to haskell: unresolved overloading question

Keean Schupke k.schupke at imperial.ac.uk
Mon Feb 21 13:34:19 EST 2005


There are problems with this approach... Instance heads are only chosen 
by the pattern not the constraints, so:

instance (Ord a, Num a) => ApproxEq a where x ~= y = (abs (x-y) < 1)

Will match any type at all (whether a member of Ord or Num or not) and 
then will
fail if the particular type is not an instance of Ord or Num.

Using incoherent-instances is almost certainly broken as it just stops 
the compiler complaining is a generic instance (like above) overlaps 
with a specific instance in the wrong way. Using the flag just makes GHC 
silently choose the _most_generic_instance_. Almost alwaysApproxEq we 
want the opposite behaviour and want GHC to choose the most specific 
instance in the case of overlap.

However it should do what you want with just -foverlapping-instances 
-fundecidable-instances.
  

    Keean.

Christian Maeder wrote

> Blair Fraser wrote:
>
>> I'm new to haskell and I'm working through the class section of the
>> gentle tutorial.  I decided to implement an ApproxEq class (just for
>> fun), but have run into problems.  The code below works fine for units
>> and bools, but gives an unresolved overloading error for Floats and
>> Doubles.  What's going on here?  What does the error message mean and
>> what did I do wrong?  (I'm in Hugs.)
>>
>> -- ApproxEq: My first class.
>> class (Eq a) => ApproxEq a where
>>   (~=) :: a -> a -> Bool
>>   x ~= y = x == y -- By default, check equality
>>
>> -- These two override default with same, just checking if it works
>> instance ApproxEq () where () ~= () = True        instance ApproxEq 
>> Bool where x ~= y = x == y
>>
>> -- These two override default with different
>> --   consider floating points equal if they differ by one or less
>> instance ApproxEq Float where x ~= y = (abs (x-y) <= 1)
>> instance ApproxEq Double where x ~= y = (abs (x-y) <= 1)
>
>
> More elegant seems to be:
>
> instance (Ord a, Num a) => ApproxEq a where x ~= y = (abs (x-y) < 1)
>
> However, this requires extensions to "Allow unsafe overlapping 
> instances":
>
> hugs -98 +O
>
> ghci -fglasgow-exts -fallow-overlapping-instances 
> -fallow-undecidable-instances -fallow-incoherent-instances
>
>> -- This one dosn't work either, but it just depends on the other two
>> instance ApproxEq a => ApproxEq [a] where
>>   [] ~= [] = True
>>   (x:xs) ~= (y:ys) = x ~= y && xs ~= ys
>>   _ ~= _ = False
>>
>> Thanks,
>> Blair
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe




More information about the Haskell-Cafe mailing list