Explicitly import instances

Matt Fenwick picture Matt Fenwick · Jan 4, 2012 · Viewed 8.3k times · Source

How do I explicitly import typeclass instances? Also, how do I do this with a qualified import?

Currently, I'm doing

import Control.Monad.Error ()

to import the monad instance that I can use for (Either String). Previously, I used

import Control.Monad.Error

I'm not satisfied with either one, because the Monad instance is implicitly imported.

Answer

ehird picture ehird · Jan 4, 2012

The inability to control imports of instances is one of the trade-offs the Haskell typeclass system makes. Here's an example in a hypothetical Haskell dialect where you can:

Foo.hs:

module Foo where

data Foo = FooA | FooB deriving (Eq, Ord)

Bar.hs:

module Bar (myMap) where

import Data.Map (Map)
import qualified Data.Map as Map

import Foo

myMap :: Map Foo Int
myMap = Map.singleton FooA 42

Baz.hs:

module Baz where

import Data.Map (Map)
import qualified Data.Map as Map

import Foo hiding (instance Ord Foo)
import Bar (myMap)

instance Ord Foo where
  FooA > FooB = True
  FooB > FooA = False

ouch :: Map Foo Int
ouch = Map.insert FooB 42 myMap

Yikes! The set myMap was created with the proper instance Ord Foo, but it's being combined with a map created with a different, contradictory instance.

Being able to do this would violate Haskell's open world assumption. Unfortunately, I don't know of a good, centralised resource for learning about it. This section of RWH might be helpful (I searched for "haskell open world assumption").