Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to circumvent existing instances (for Failure) in Haskell?

I'm in a monad transformer with IO and I'd like to define my own instance for Failure.

Because Failure already defines instances for IO and for MonadTrans, I cannot even build my own overlapping instance.

As far as I know, I have four options left:

  1. Newtyping IO:
    This is a little bit awkward, I would need to derive all that I want to change, and redefine the rest.
  2. Hacking Failure to separate the class itself into it's own Module:
    I would move the class definition into a submodule Control.Failure.Class
  3. Creating a Simple wrapper module for Failure without reexporting the instances
  4. Removing MonadTrans from my Monad Transformer

Do you know any other option? What do you think?

like image 933
Sebastian Wagner Avatar asked Mar 21 '14 12:03

Sebastian Wagner


1 Answers

A newtype wrapper is the standard approach to such a problem. The GeneralizedNewtypeDeriving extension makes optionally deriving instances from the wrapped monad a breeze.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- | Your custom monad transformer
newtype YourMonadT e m r = 
  YourMonadT (EitherT e m r)
  -- Easily derive the instances using the GeneralizedNewtypeDeriving
  deriving (Functor, Applicative, Monad, MonadIO)

instance Failure e (YourMonadT e m) where
  failure = error "TODO: implement me however you want"
like image 145
Nikita Volkov Avatar answered Oct 26 '22 23:10

Nikita Volkov