
On 15 Aug 2013, at 19:49, 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"
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