The DatatypeContexts language extension has been marked deprecated for over ten years.The best summary for why is on Prime (archive link) NoDatatypeContexts – Haskell Prime
It’s widely repeated that this is an anti-feature and should be removed any day now. However, the explanation as to why it does not work, taken from that archive page, does not seem to apply today.
Quoting and abbreviating, the problem is stated to be that given
data Eq a => Foo a = Constr a
you cannot write the following
isEq (Constr x) (Constr y) = x == y
because the compiler doesn’t know that there is an Eq a instance from the datatype context.
This is what i see with GHC 9.0.2:
$ stack ghci --ghci-options="-XDatatypeContexts"
...
-XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language.
...
λ> data Eq a => Foo a = Constr a
λ> isEq (Constr x) (Constr y) = x == y
λ> :t isEq
isEq :: Eq a => Foo a -> Foo a -> Bool
It seems to me the compiler figured out the Eq constraint just fine.
The article goes on to say
In fact, we cannot even write
getVal :: Foo a -> a getVal (Constr x) = x
And yet
λ> getVal (Constr x) = x
λ> :t getVal
getVal :: Eq a => Foo a -> a
The above was all in a GHCi session but I see the same results if I compile and run a program instead. The problem does occur if you write type signatures for these functions. Was this the same situation a decade ago? Or did the instances not work back then?