[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