[Haskell-beginners] Compiler can't deduce Bool as instance of ToField
tom.davie at gmail.com
Thu Aug 15 20:11:28 CEST 2013
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:
>>> 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.
More information about the Beginners