处理Haskell中的歧义现象
我正在导入处理Haskell中的歧义现象,haskell,module,Haskell,Module,我正在导入数据.Text和数据.List以及它们各自的find函数 导入数据.Text 导入数据。列表 我的清单=[4,2,4,5,6,2,6] 查找(\a->a==5)我的\u列表 上述代码导致以下错误 Ambiguous occurrence ‘find’ It could refer to either ‘Data.Text.find’, imported from ‘Data.Text’ or ‘Data.List.find’,
数据.Text
和数据.List
以及它们各自的find
函数
导入数据.Text
导入数据。列表
我的清单=[4,2,4,5,6,2,6]
查找(\a->a==5)我的\u列表
上述代码导致以下错误
Ambiguous occurrence ‘find’
It could refer to
either ‘Data.Text.find’, imported from ‘Data.Text’
or ‘Data.List.find’,
imported from ‘Data.List’
(and originally defined in ‘Data.Foldable’)
是在此处使用Data.List.find(\a->a==5)my_List
的唯一解决方案,还是合格的导入
让我印象深刻的是
Data.List.find(\a->a==5)我的列表
-->只有5个
Data.Text.find(\a->a==5)我的\u列表
-->错误:无法将预期类型“Text”与实际类型“[Integer]”匹配
从find
函数签名中,编译器显然能够理解Data.Text.find
不适用于[Integer]
。他不能使用此信息来决定使用find
的哪个实例,并且在这种情况下,自动使用find
fromData.List
是在此处使用Data.List.find(\a->a==5)my_List
的唯一解决方案,还是合格的导入
据我所知,是的,没有其他解决办法 编译器不会尝试同时检查两个选项并使用使代码编译的选项。在最普遍的情况下,这可能导致指数级爆炸。考虑,例如,
foo a1 a2 .... aN
其中,a1
中的每一个<代码>从两个不同的模块导入一个。尝试哪种组合类型检查原则上需要测试2^N个组合
此外,程序员总是有可能打算使用模块中的标识符,但他们犯了错误,代码没有进行类型检查。在这种情况下,来自另一个模块的相同标识符可能会改为类型检查,使代码编译,但产生错误的结果。(我知道,这是一个相当做作的例子。)
请注意,如果在导入模块中,您只需要使用两个
find
s中的一个,则可以隐藏另一个:
import Data.Text hiding (find)
import Data.List
或者,您可以提供显式不相交的导入列表:
import Data.Text (pack)
import Data.List (find, zip)
如果同时需要find
s,则可以为模块提供较短的名称
import Data.Text as T
import Data.List as L
然后使用
L.find
消除歧义。除了双重导入的标识符外,您不需要较短的模块名。如果使用import-qualified
,则需要为所有导入的标识符指定模块名称。只是澄清一下,这是否意味着Haskell中不存在多重分派,您可以多次使用不同的参数类型定义相同的函数名,而编译器将完成这项工作?还是我误解了something@Jivan不是那样的。您可以使用TypeClass实现多个分派。例如,show True
和show(42::Int)
都可以工作,并且有单独的实现,让编译器根据类型(实例解析)选择正确的实现。这两个实现甚至可以编写在不同的模块中。必须要求声明一个类并定义实例:在两个模块中使用相同的名称是不够的。“据我所知,是的,没有其他解决方案。”-这不是真的,除非您需要在模块中的不同位置使用这两个函数。如果只需要一个,可以在import语句中隐藏另一个,或者更好的做法是使用显式导入列表,而不是从模块中导入所有内容。@RobinZigmond是的,考虑到OP示例,我认为这是理所当然的,但也许我错了。