明确导入实例

时间:2012-01-04 14:38:23

标签: haskell import typeclass

如何显式导入类型类实例?另外,如何使用合格的导入来执行此操作?

目前,我正在做

import Control.Monad.Error ()

导入我可用于(Either String)的monad实例。以前,我用过

import Control.Monad.Error

我对其中任何一个都不满意,因为Monad实例是隐式导入的。

3 个答案:

答案 0 :(得分:46)

无法控制实例的导入是Haskell类型类系统所做的权衡之一。这是一个假设的Haskell方言的例子,你可以:

<强> 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

糟糕!集合myMap是使用正确的instance Ord Foo创建的,但它与使用不同的,矛盾的实例创建的地图相结合。

能够做到这一点会违反Haskell的开放世界假设。不幸的是,我不知道一个好的,集中的资源来学习它。这section of RWH可能会有所帮助(我搜索了“haskell开放世界假设”)。

答案 1 :(得分:7)

你不能。实例总是隐式导出,因此您无法显式导入它们。顺便说一下,Either e Monad实例现在位于Control.Monad.Instances

答案 2 :(得分:2)

虽然一般正确的答案是“不,你不能”,但我建议这个可怕的解决方案:

复制+粘贴

查看所需模块的库源代码,并将必要的数据声明,导入和函数定义复制/粘贴到您自己的代码中。 不要复制您不想要的实例。

根据手头的问题,ghc type system extensions OverlappingInstancesIncoherentInstances可能是替代解决方案,但这可能无法解决base库的任何问题