Haskell Functional Dependence ab & # 8594; c depending on c?

Consider the following Haskell code:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-} class C abc | ab -> c instance C (l (i,j)) (rij) j instance C (lij) (r (i,j)) j -- Conflict between the following two lines instance C (l (i,j)) (r (i,j)) j instance C (lij) (rij) j 

Here the GHC gives a functional dependency error between the last two lines. If I omit any of the last two instance declarations, the code compiles. I tried an analog using type families, which also caused a conflict. My first question is: why are the last two lines conflicting while other ads are working fine?

Also, if I changed the most recent line to

 instance C (lij) (rij) i 

GHC accepts the code. This seems rather strange since the only thing that changes is a dependent variable of type c. Can anyone explain this behavior?

+6
source share
1 answer

The last two instances have a conflicting union. Let me use completely different variable names:

 C (ac (d,e)) (bc (d,e)) e vs. C (ac (d,e)) (bc (d,e)) (d,e) 

In particular, your l from the third instance can be unified with a constructor of a type that already has an argument.

Changing your j to i does the latter instead:

 C (ac (d,e)) (bc (d,e)) c 

I still do not understand why this does not give a complaint. Perhaps this is because you can assign types such as c = e , but not such as e = (d,e) (which will give an infinite type that Haskell does not allow), but this still seems dubious. Perhaps this is even a GHC bug.

Other combinations of instances do not conflict, because when you try to combine them, you find yourself in contradictions similar to the above e = (d,e) , but in independent parts, so they cannot match.

+6
source

Source: https://habr.com/ru/post/982457/


All Articles