mzero is a member of the MonadPlus class. In particular,
mzero :: MonadPlus m => ma
The monad that is used for your unify function is an LP , which is actually a BackT created using ST . In addition, you define a MonadPlus instance for BackT , which depends on that instance for the main monad. Since ST does not have such an instance, the GHC is mocking you.
This is the important part:
instance (MonadPlus m) => MonadPlus (BackT m) where mzero = BT (\s -> mzero) f `mplus` g = BT (\s -> (run f) s `mplus` (run g) s)
In plain English: this is an instance of MonadPlus for BackT m , provided that m also an instance of MonadPlus . Since m initialized by ST , you need this instance for ST . I wonder how you could define a reasonable instance of MonadPlus without delegation. I have an idea:
instance MonadPlus (BackT m) where mzero = BT (const $ return []) mplus (BT f) (BT g) = BT $ \a -> do fs <- fa gs <- ga return $ fs ++ gs
This instance basically combines the two output lists. Hope this fits your needs.
source share