#4259: Relax restrictions on type family instance overlap
----------------------------------------+-----------------------------------
    Reporter:  lilac                    |       Owner:                  
        Type:  feature request          |      Status:  new             
    Priority:  normal                   |   Milestone:  7.6.1           
   Component:  Compiler (Type checker)  |     Version:  6.12.1          
    Keywords:                           |          Os:  Unknown/Multiple
Architecture:  Unknown/Multiple         |     Failure:  None/Unknown    
  Difficulty:                           |    Testcase:                  
   Blockedby:                           |    Blocking:                  
     Related:                           |  
----------------------------------------+-----------------------------------

Comment(by duairc):

 I'd just like to point out that the following works (using functional
 dependencies):

 {{{
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}

 class (Monad (Inner m), Monad m) => MonadLayer m where
     type Inner m :: * -> *
     lift :: Inner m a -> m a

 class (Monad b, Monad m) => MonadBase b m | m -> b where
     liftBase :: b a -> m a

 instance MonadBase IO IO where
     liftBase = id

 instance (MonadLayer m, MonadBase b (Inner m)) => MonadBase b m where
     liftBase = lift . liftBase
 }}}

 While the following (using type families) does not:

 {{{
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}

 class (Monad (Inner m), Monad m) => MonadLayer m where
     type Inner m :: * -> *
     lift :: Inner m a -> m a

 class (Monad (Base m), Monad m) => MonadBase m where
     type Base m :: * -> *
     liftBase :: Base m a -> m a

 instance MonadBase IO where
     type Base IO = IO
     liftBase = id

 instance (MonadLayer m, MonadBase (Inner m)) => MonadBase m where
     type Base m = Base (Inner m)
     liftBase = lift . liftBase
 }}}

 The example using functional dependencies will work even if the instances
 are defined in different modules.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4259#comment:19>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to