Consider the following code example:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-} -- Is there a way to avoid this?

-- A generic class with a generic function.
class Foo a where
  foo :: a -> a

-- A specific class with specific functions.
class Bar a where
  bar :: a -> a
  baz :: a -> a

-- Given the specific class functions, we can implement the generic class function.
instance Bar a => Foo a where
  foo = bar . baz

-- So if a type belongs to the specific class...
instance Bar String where
  bar = id
  baz = id

-- We can invoke the generic function on it.
main :: IO ()
main =
  putStrLn (foo "bar")

(My actual code is way more elaborate; this is a minimal boiled-down case to demonstrate the pattern.)

It isn't clear to me why UndecidableInstances are needed here - the type parameter a appears once in both sides of the Bar a => Foo a, so I expected things to "just work". I'm obviously missing something here. But at any rate, is there a way to do this without using UndecidableInstances?

Edit
Report