Typeclass instance with functional dependencies doesn't work?

Your instance works just fine, actually. Observe.

Your instance works just fine, actually. Observe: main = print $ two (3 :: Int, 4 :: Int) This works as expected. So why doesn't it work without the type annotation, then?

Well, consider the tuple's type: (3, 4) :: (Num t, Num t1) => (t, t1). Because numeric literals are polymorphic, nothing requires them to be the same type. The instance is defined for (a, a), but the existence of that instance won't tell GHC to unify the types (for a variety of good reasons).

Unless GHC can deduce by other means that the two types are the same, it won't choose the instance you want, even if the two types could be made equal. To solve your problem, you could just add type annotations, as I did above. If the arguments are coming from elsewhere it's usually unnecessary because they'll already be known to be the same type, but it gets clumsy quickly if you want to use numeric literals.An alternative solution is to note that, because of how instance selection works, having an instance for (a, a) means that you can't write an instance like (a, b) as well even if you wanted to.

So we can cheat a bit, to force the unification using the type class, like this: instance (a ~ b) => Pair (a,b) a where That needs the TypeFamilies extension for the ~ context, I think. What this does is allow the instance to match on any tuple at first, because instance selection ignores the context. After choosing the instance, however, the a ~ be context asserts type equality, which will produce an error if they're different but--more importantly here--will unify the type variables if possible.

Using this, your definition of main works as is, without annotations.

Thanks, very interesting! – Landei 2 days ago.

The problem is that a literal number has a polymorphic type. It is not obvious to the typechecker that both literals should have the same type (Int). If you use something that is not polymorphic for your tuples, your code should work.

Consider these examples: *Main> two (3,4) :1:1: No instance for (Pair (t0, t1) a0) arising from a use of `two' Possible fix: add an instance declaration for (Pair (t0, t1) a0) In the expression: two (3, 4) In an equation for `it': it = two (3, 4) *Main> let f = id :: Int -> Int -- Force a monomorphic type *Main> two (f 3,f 4) 4 *Main> two ('a','b') 'b' *Main> two ("foo","bar") "bar" *Main> two (('a':),('b':)) "cde" "bcde" *Main.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions