如何告诉Haskell不要从两个模块导入相同的实例



我使用以下类型:

module T where
class T a where
  v :: a

我实现的T Int的一个实例:

import T
import A (av)
instance T Int where
  v = 0
main = putStrLn (av ++ show v)

和一个我想使用的值的模块,它也有一个T Int的实例。

module A where
import T
instance T Int where
  v = 0
av = "value from A"

问题是这不起作用:

$ runghc Main.hs 
Main.hs:4:9:
    Duplicate instance declarations:
      instance T Int -- Defined at Main.hs:4:9-13
      instance T Int -- Defined at A.hs:3:9-13

Haskell抱怨同一个实例有两个声明。我如何告诉他不从B导入实例,或者统一两个实例,或者只使用Main的实例?

不幸的是,您无法控制实例的导入和导出方式;参见Haskell导入有副作用吗?

这意味着您必须重构代码,以确保实例仅在一个文件中定义。一般来说,最好只在定义类或数据类型的文件中定义一个实例——事实上,对于不遵循此规则的"孤立"实例,甚至会有一个警告。(请参阅Haskell中的孤立实例,详细讨论为什么应该避免孤立实例。)

然而,如果由于某些原因无法做到这一点,您仍然可以随意选择其中一个文件来保留它,甚至创建一个新模块,供需要该特定实例的所有文件导入。

更一般地说,你如何处理这两个实例做了不同的事情的可能性,比如:
instance T Int where v = 0
{- And in a different file: -}
instance T Int where v = 1

如果不显著改变Haskell类型类系统的工作方式,确实没有立即明显的方法来消除这两者的歧义。

由于其中一个实例是您自己编写的,因此只需删除它即可。由于它与预定义的模块相同,因此只需在需要使用它的地方导入该模块即可。

相关内容

  • 没有找到相关文章

最新更新