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

Daniel Fischer daniel.is.fischer at web.de
Mon Feb 21 18:34:27 EST 2005


Am Montag, 21. Februar 2005 17:32 schrieb Christian Maeder:
> 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
>

For the original code, no extensions are necessary (and neither hugs nor ghc 
does complain).

Probably something like

ApproxEq> 1.5 ~= 2.4
ERROR - Unresolved overloading
*** Type       : (Fractional a, ApproxEq a) => Bool
*** Expression : 1.5 ~= 2.4

happened, that doesn't mean there is any problem with the code, only that the 
interpreter doesn't know what type 1.5 and 2.4 have. Adding a type to either
resolves:

ApproxEq> 1.5 ~= (2.4::Double)
True

ApproxEq> [1,2,3] ~= [1.6,2.8,3.9999]
ERROR - Unresolved overloading
*** Type       : (Fractional a, ApproxEq a) => Bool
*** Expression : [1,2,3] ~= [1.6,2.8,3.9999]

ApproxEq> [1,2,3] ~= ([1.6,2.8,3.9999]::[Float])
True

That's a very common problem for newbies, so don't panic.
In older versions of hugs (November 2002, e.g.), you would have got an 
unresolved overloading also from entering [] to the prompt (this is no longer 
so). If such things happen, add an explicit typing, if that doesn't help, 
then you have a problem.

To deepen the confusion, hugs has no problems with

Prelude> 1.5 == 1.5
True

I'm not quite sure why this works, must be due to type defaulting, however, 
including

default (Double)

doesn't help ApproxEq, so there must be more to it in the (==) case.

BTW, if you add Christian's instance, for hugs, -98 +o (lower case o, allow 
overlapping instances) suffices, for ghci, -fallow-incoherent-instances is 
not necessary.

Stay with Haskell, it's great (though not perfect)!

Daniel


More information about the Haskell-Cafe mailing list