Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理Haskell中的歧义现象_Haskell_Module - Fatal编程技术网

处理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
from
Data.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示例,我认为这是理所当然的,但也许我错了。