[Haskell-cafe] Ambiguous type signature in class declaration
Benjamin Franksen
benjamin.franksen at bessy.de
Wed Apr 27 16:12:44 EDT 2005
On Wednesday 27 April 2005 19:12, Bo Herlin wrote:
> I am trying to make a class like this:
> > class CRank a b where
> > rank :: a -> b -> Maybe Integer -- Nothing means b is out of range
>
> or badly constructed
>
> > unrank :: a -> Integer -> Maybe b -- Nothing means rank is out of
> > range count :: a -> Maybe Integer -- Nothing means infinity
>
> but all i get is
>
> ERROR "./Cafe.lhs":8 - Ambiguous type signature in class declaration
> *** ambiguous type : CRank a b => a -> Maybe Integer
> *** assigned to : count
The type variable 'b' does not appear on the right side of the '=>' in the
type of 'count'. The compiler complains about an 'ambigous type signature',
because the type of 'b', and hence of 'count', cannot be determined from its
arguments. Thus, if there are instances
instance CRank Prime Integer where ...
instance CRank Prime Int where ...
then these would have different implementations for 'count'. Which one should
be chosen if you write
count Prime
the infinite result for Integers or the (presumably) finite result for Ints?
Functional dependencies only help if you never want to declare both of the
above instances. If this is not the case (and therefore you don't want to use
a fundep 'a -> b'), you can disambiguate the signature by giving it a second
(phantom) argument to indicate the type:
class CRank a b where
...
count :: a -> b -> Maybe Integer
-- implementations must not evaluate 2nd argument
and call it like this
let n = count Prime (undefined::Integer)
Admittedly, the extra argument is not very nice and neither is the
'undefined'. Another trick is to split the class:
class Countable a where
count :: a -> Maybe Integer -- Nothing means infinity
class Countable a => CRank a b where
rank :: ...
...
Ben
More information about the Haskell-Cafe
mailing list