Compiler can't deduce Bool as instance of ToField

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Compiler can't deduce Bool as instance of ToField

Bryan Vicknair
> > 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?



Reply | Threaded
Open this post in threaded view
|

Compiler can't deduce Bool as instance of ToField

Thomas Davie

On 15 Aug 2013, at 19:49, Bryan Vicknair <bryanvick at gmail.com> wrote:

>>> 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.

That?s not it here.  What you?re saying in the first case is ?no matter what numeric type you want, I can provide it?.  This is true, because the compiler can decide that 5 can indeed be any numeric type.  In the latter case you make the promise ?no matter what type you want, as long as you can show it, I can provide it?, but it?s false.  I can say ?well okay, give me an Int? and your function can not provide it to me, despite telling me in its type signature that it can.

Tom Davie




Reply | Threaded
Open this post in threaded view
|

Compiler can't deduce Bool as instance of ToField

David McBride
In reply to this post by Bryan Vicknair
The type of 5:

Prelude> :t 5
5 :: Num a => a

That's why it works.  The literal's type uses the type class.  Other fun
stuff:

Prelude> :t "asdf"
"asdf" :: [Char]

Prelude> :set -XOverloadedStrings

Prelude> :t "asdf"
"asdf" :: Data.String.IsString a => a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130815/bef4de2b/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

Compiler can't deduce Bool as instance of ToField

Kim-Ee Yeoh
Administrator
In reply to this post by Bryan Vicknair
On Fri, Aug 16, 2013 at 12:49 AM, Bryan Vicknair <bryanvick at gmail.com>wrote:

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

The literal '5' is *known* to be of the *polymorphic* type (Num a => a).
Ints and Floats are monomorphic instances of this polymorphic type. See

http://www.haskell.org/onlinereport/basic.html#numeric-literals


>  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.
>

The part "if a literal can be considered part of a typeclass in more than
one way" isn't how you want to think about them (see link). Good attempt
though.

> 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?

You enforce monomorphism by specifying type signatures where appropriate.
In some cases, a light touch is all that's needed because type inference
does the rest.

-- Kim-Ee
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130816/9b92617d/attachment.htm>