[Haskell-beginners] Compiler can't deduce Bool as instance of ToField

Bryan Vicknair bryanvick at gmail.com
Thu Aug 15 19:49:54 CEST 2013


> > Bryan Vicknair:
> > postgresql-simple declares Bool as an instance of the ToField class.  The
> > compiler can't deduce that given this simple code however:
> >
> >   import Database.PostgreSQL.Simple.ToField (ToField(..))
> >
> >   foo :: (ToField a) => a
> >   foo = True
> >
> >
> > It fails with this error:
> >
> >   Db.hs:64:7:
> >       Could not deduce (a ~ Bool)
> >       from the context (ToField a)
> >         bound by the type signature for foo :: ToField a => a
> >         at Db.hs:63:8-23
> >         `a' is a rigid type variable bound by
> >             the type signature for foo :: ToField a => a at Db.hs:63:8
> >       In the expression: True
> >       In an equation for `foo': foo = True
> >   Failed, modules loaded: none.
> >
> > What am I missing?
> >

> Oliver Charles 
> You have declared that foo is *any* type that has a ToField instance,
> allowing the caller of foo to determine the type at their will. However,
> your implementation of foo is more specific and requires a is actually Bool
> and nothing else.
> On 14 Aug 2013 10:24, "Bryan Vicknair" <bryanvick at gmail.com> wrote:

I see.  I was confused, because the following works:

  bar :: (Num a) => a
  bar = 5

I guess it is because the literal '5' could be an Int or a Float, and the type
system doesn't know.

When I saw that the following does not work...::

  bar :: (Show a) => a
  bar = False

...it made a bit more sense.  It seems that if a literal can be considered part
of a typeclass in more than one way, you can declare that literal to be of that
typeclass.  However, if there is only one way for a literal to belong to a
typeclass, then you can't.

Are there other literals (besides (Num a) => [a]) that don't have a concrete
type like literal numbers?  If I understand correctly, -XOverloadedStrings
turns all literal strings into IsString instead of [Char], so that seems to be
another case.

I don't have a need for this, but now I'm curious: is there a way to declare
that all literal numbers in a module are of a certain concrete type?  Something
like -XAllNumbersAreInt8?




More information about the Beginners mailing list