8
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?