为什么Haskell递归地导入实例?为什么不只从指定模块导入所有实例?

为什么Haskell递归地导入实例?为什么不只从指定模块导入所有实例?,haskell,import,instance,typeclass,Haskell,Import,Instance,Typeclass,摘自Haskell 2010年报告第5.4节。当且仅当导入声明链指向包含实例声明的模块时,实例声明才在范围内 我确实用一个简单的程序进行了检查,它确实递归地引入了作用域实例,即使它们不直接在导入的模块中 为什么这种递归行为是可取的/必要的?如果它只将目标模块中包含的所有实例都纳入范围,那会不会太糟糕?我不想导入一个特定实例。这真的会使进口数量增加这么多吗?有没有一些根本的/汇编的/历史的原因不能这样做 我目前的印象是,对孤立实例的敌意很大一部分可能是基于这一前提,因为一个不好的风险是,您无意中从

摘自Haskell 2010年报告第5.4节。当且仅当导入声明链指向包含实例声明的模块时,实例声明才在范围内

我确实用一个简单的程序进行了检查,它确实递归地引入了作用域实例,即使它们不直接在导入的模块中

为什么这种递归行为是可取的/必要的?如果它只将目标模块中包含的所有实例都纳入范围,那会不会太糟糕?我不想导入一个特定实例。这真的会使进口数量增加这么多吗?有没有一些根本的/汇编的/历史的原因不能这样做


我目前的印象是,对孤立实例的敌意很大一部分可能是基于这一前提,因为一个不好的风险是,您无意中从某个深埋的模块导入了一个不需要的孤立实例。

我相信ehird在这里的回答也为这个问题提供了答案。 如果实例不是以递归方式导入的,那么就有可能实现与示例中相同的效果

可以使用某个Bar.hs模块中的给定Ord实例创建一个函数,导入一些Data.Ord模块。然后,该函数可能用于其他Baz.hs模块,该模块定义自己的Ord实例,而不导入Data.Ord。因此,它会造成不必要的不一致。我最初认为这个问题只适用于特定的实例导入,但它也适用于这种情况


有必要避免这样的问题,即导入的每个实例和某个模块范围内的实例都会自动重新导出到任何其他模块,这意味着传递性是不可避免的。

我相信ehird在这里的回答也为这个问题提供了答案。 如果实例不是以递归方式导入的,那么就有可能实现与示例中相同的效果

可以使用某个Bar.hs模块中的给定Ord实例创建一个函数,导入一些Data.Ord模块。然后,该函数可能用于其他Baz.hs模块,该模块定义自己的Ord实例,而不导入Data.Ord。因此,它会造成不必要的不一致。我最初认为这个问题只适用于特定的实例导入,但它也适用于这种情况


必须避免这样的问题,即导入的每个实例以及某个模块范围内的实例都会自动重新导出到任何其他模块,这意味着传递性是不可避免的。

由于无法指定排除实例,因此如果导入实例,则这些实例会在模块中定义,因此也会导出这些实例,因为您导出了范围内的所有内容。@Willem Van Onsem。实例导入范围不能与定义范围分开吗?这听起来像是一个实现细节。也许这就是GHC的编码方式。但我不知道为什么它是这样编码的。我认为他们受到不同的对待。实例以不可见的方式导入/导出,而类和函数必须在export list.tl中明确显示;因为连贯性很重要。投票决定重新开放。这个问题并非真正基于意见;它的答案来自于Haskell中TypeClass如何工作的一个基本的、有详细文档记录的方面。由于您不能指定排除实例,如果您导入实例,那么这些实例将在模块中定义,因此您也可以导出这些实例,因为您导出了范围内的所有实例。@Willem Van Onsem。实例导入范围不能与定义范围分开吗?这听起来像是一个实现细节。也许这就是GHC的编码方式。但我不知道为什么它是这样编码的。我认为他们受到不同的对待。实例以不可见的方式导入/导出,而类和函数必须在export list.tl中明确显示;因为连贯性很重要。投票决定重新开放。这个问题并非真正基于意见;它的答案来自于Haskell中TypeClass如何工作的一个基本的、有充分记录的方面。