我正在导入Data.Text和Data.List,它们各自的find功能崩溃了。
import Data.Text\nimport Data.List\n\nmy_list = [4, 2, 4, 5, 6, 2, 6]\nfind (\\a -> a == 5) my_list\nRun Code Online (Sandbox Code Playgroud)\n上面的代码会导致以下错误
\n Ambiguous occurrence \xe2\x80\x98find\xe2\x80\x99\n It could refer to\n either \xe2\x80\x98Data.Text.find\xe2\x80\x99, imported from \xe2\x80\x98Data.Text\xe2\x80\x99\n or \xe2\x80\x98Data.List.find\xe2\x80\x99,\n imported from \xe2\x80\x98Data.List\xe2\x80\x99\n (and originally defined in \xe2\x80\x98Data.Foldable\xe2\x80\x99)\nRun Code Online (Sandbox Code Playgroud)\n是这里使用的唯一解决方案Data.List.find (\\a -> a == 5) my_list,还是合格的进口?
让我印象深刻的是
\n Ambiguous occurrence \xe2\x80\x98find\xe2\x80\x99\n It could refer to\n either \xe2\x80\x98Data.Text.find\xe2\x80\x99, imported from \xe2\x80\x98Data.Text\xe2\x80\x99\n or \xe2\x80\x98Data.List.find\xe2\x80\x99,\n imported from \xe2\x80\x98Data.List\xe2\x80\x99\n (and originally defined in \xe2\x80\x98Data.Foldable\xe2\x80\x99)\nRun Code Online (Sandbox Code Playgroud)\n从find函数签名来看,编译器显然能够理解它Data.Text.find不适用于[Integer]. 他不能使用此信息来决定find使用哪个实例,并且在本例中自动使用findfromData.List吗?
是这里使用的唯一解决方案
Data.List.find (\a -> a == 5) my_list,还是合格的进口?
据我所知,是的,没有其他解决方案。
编译器不会尝试对这两个选项进行类型检查,而是使用使您的代码能够编译的选项。在最一般的情况下,这可能会导致指数式的爆炸。考虑,例如,
foo a1 a2 .... aN
Run Code Online (Sandbox Code Playgroud)
其中a1..中的每一个aN都是从两个不同的模块导入的。尝试哪种组合类型检查原则上需要测试 2^N 种组合。
此外,程序员总是有可能想要使用模块中的标识符,但他们犯了一个错误,并且代码没有进行类型检查。在这种情况下,来自其他模块的相同标识符可能会进行类型检查,从而使代码编译但产生错误的结果。(我知道,这是一个相当人为的例子。)
请注意,如果在导入模块中您只需要使用两个中的一个find,则可以隐藏另一个:
import Data.Text hiding (find)
import Data.List
Run Code Online (Sandbox Code Playgroud)
或者,您可以提供显式的不相交导入列表:
import Data.Text (pack)
import Data.List (find, zip)
Run Code Online (Sandbox Code Playgroud)
如果您需要两个find,您可以为模块提供一个较短的名称
import Data.Text as T
import Data.List as L
Run Code Online (Sandbox Code Playgroud)
然后使用 消除歧义L.find。除了双重导入的标识符之外,您不需要更短的模块名称。如果您import qualified改为使用,则需要为所有导入的标识符指定模块名称。
| 归档时间: |
|
| 查看次数: |
469 次 |
| 最近记录: |