Skip to content

Stack overflow / OOM with UndecidableSuperClasses in 9.2

Summary

Adding a recursive constraint to a typeclass on an associated type family compiles fine and runs fine in GHC < 9.2, but causes stack overflow or memory issues in GHC 9.2 (depending on optimization).

Original reddit discussion: https://www.reddit.com/r/haskell/comments/riaw00/stack_overflow_oom_with_undecidablesuperclasses/

Steps to reproduce

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableSuperClasses #-}

import Data.Kind (Type)

class (Monad m, MonadFoo (FooM m)) => MonadFoo m where
  type FooM m :: Type -> Type
  runFoo :: FooM m a -> m a

newtype MyMonad m a = MyMonad { runMyMonad :: m a }
  deriving (Functor, Applicative, Monad)

instance Monad m => MonadFoo (MyMonad m) where
  type FooM (MyMonad m) = MyMonad m
  runFoo = id

main :: IO ()
main = runMyMonad foo

foo :: MonadFoo m => m ()
foo = runFoo $ return ()

ghc Foo.hs && ./Foo works with GHC 9.0.1, but not GHC 9.2.1. The GHC 9.2 change to make dicts strict by default is probably the cause of this, which makes me think there's a regression with GHC 9.2 and UndecidableSuperClasses, since it seems like any recursive superclass definitions would cause infinite loops with strict dicts.

Expected behavior

I would expect this to compile and run fine across all GHC versions supporting UndecidableSuperClasses.

Environment

  • GHC version used:

Optional:

  • Operating System:
  • System Architecture:
Edited by Brandon Chinn
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information