Skip to content

Exactly how much "coinductive" constraint resolution do we do?

Summary

The following program type checks:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}

class C where
instance C => C

class D a where
instance D a => D a

class E a => E a where
instance E a

class F a => F a where
instance F a => F a

foo :: C => a
foo = undefined

bar :: D a => a
bar = undefined

baz :: E a => a
baz = undefined

quup :: F a => a
quup = undefined

I understand how operationally the dictionary is fed itself in a letrec, but does seem to undermine the notion of => as logical implication. We could have alternatively banned this, and the constraint solver would fail to terminate.

Proposed improvements or changes

I'm not sure what this could be called (hence the scare quotes on "coinductive"), what the rules are, or when/where it came about (version of GHC, paper, etc.)

Environment

  • The example program is tested with 8.10
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information