
I am trying to upgrade some update facility in my program to allow for IO: class Updater modelType updateType where update :: updateType -> modelType -> Maybe modelType class UpdaterIO modelType updateType where updateIO :: updateType -> modelType -> IO (Maybe modelType) pureUpdateToIO :: (updateType -> modelType -> (Maybe modelType)) -> updateType -> modelType -> IO (Maybe modelType) pureUpdateToIO updateFunction update model = return $ updateFunction update model instance (Updater modelType updateType) => UpdaterIO modelType updateType where updateIO = pureUpdateToIO update My code still works for all my old Updater instances even when I use them in the IO monad: do maybeUpdatedModel <- updateIO newUpdate oldModel So far so good. However, when I try to upgrade one of the Updater instances to an UpdateIO instance I get into a kind of a catch 22 situation where not only maybeUpdatedModel = update newUpdate oldModel results in a "No instance for Updater [...] [...]" compiler error as expected, but also do maybeUpdatedModel <- updateIO newUpdate oldModel unexpectedly results in an "Overlapping instances for UpdaterIO [...] [...]" compiler error. Where one of the overlapping instance declarations is: instance (Updater modelType updateType) => UpdaterIO modelType updateType How is that possible? Cheers, Jeroen