Created
April 19, 2016 04:03
-
-
Save shmookey/f87961fa1f6199f04782bccf2e2b7723 to your computer and use it in GitHub Desktop.
Overlapping instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
-- Let's say our project involves a number of similarly-structured reader monads. | |
-- Their data types might look like this: | |
data Conf = Conf {} | |
data ConfReader a = ConfReader { runConfReader :: Conf -> IO a } | |
-- Their instances for `Functor`, `Applicative` and `Monad` will be almost identical. | |
-- We only need to know how to construct and run them: | |
class SimpleReader m c | m -> c, c -> m where | |
run :: m a -> (c -> IO a) | |
make :: (c -> IO a) -> m a | |
-- So let's start with `Functor`. We need `FlexibleInstances` to use a constraint | |
-- on an instance, and `UndecidableInstances` to allow `c` in the context but | |
-- not the head. | |
instance SimpleReader m c => Functor m where | |
fmap f ma = make $ \c -> f `fmap` run ma c | |
-- But somehow this causes overlapping instances for Functor! | |
-- test.hs:24:30: | |
-- Overlapping instances for Functor IO arising from a use of ‘fmap’ | |
-- Matching instances: | |
-- instance Functor IO -- Defined in ‘GHC.Base’ | |
-- instance SimpleReader m c => Functor m -- Defined at test.hs:23:10 | |
-- In the expression: f `fmap` run ma c | |
-- In the second argument of ‘($)’, namely ‘\ c -> f `fmap` run ma c’ | |
-- In the expression: make $ \ c -> f `fmap` run ma c | |
main = return () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment