我使用以下类型类:
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抱怨说同一个实例有2个声明。如何告诉他不要从B
导入实例,或统一这两个实例,或仅使用Main
中的实例?
答案 0 :(得分:8)
不幸的是,您无法控制实例导入和导出的方式;见Do Haskell imports have side effects?。
这意味着您必须重构代码以确保实例仅在一个文件中定义。通常,最好只在文件中定义一个定义类或数据类型的实例 - 实际上,甚至还有关于“孤儿”实例的警告,这些实例不遵循此规则。 (请查看Orphaned instances in Haskell,详细讨论为什么要避免使用孤立实例。)
但是,如果由于某种原因这是不可能的,您仍然可以随意选择其中一个文件来保存它,甚至创建一个新模块,以便由需要该特定实例的所有文件导入。
更一般地说,您如何处理这两个实例不同事物的可能性,例如:
instance T Int where v = 0
{- And in a different file: -}
instance T Int where v = 1
在没有显着改变Haskell类型类系统的工作方式的情况下,确实没有明显的方法可以消除歧义。
由于您自己编写了其中一个实例,因此只需删除该实例即可。由于它与预定义的相同,只需在需要使用它的地方导入该模块。