haskell - 在 Haskell 中处理模棱两可的事件
问题描述
我正在导入两者Data.Text
,Data.List
并且它们各自的find
功能都崩溃了。
import Data.Text
import Data.List
my_list = [4, 2, 4, 5, 6, 2, 6]
find (\a -> a == 5) my_list
上面的代码导致以下错误
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) my_list
--> Just 5
Data.Text.find (\a -> a == 5) my_list
--> error: Couldn't match expected type ‘Text’ with actual type ‘[Integer]’
从find
函数签名中,编译器显然能够理解Data.Text.find
不适用于[Integer]
. 他不能使用这些信息来决定使用哪个实例find
,在这种情况下,自动使用find
fromData.List
吗?
解决方案
是这里使用的唯一解决方案
Data.List.find (\a -> a == 5) my_list
,还是合格的进口?
据我所知,是的,没有其他解决方案。
编译器不会尝试对这两个选项进行类型检查并使用使您的代码编译的选项。在最普遍的情况下,这可能会导致指数级的爆炸式增长。考虑,例如,
foo a1 a2 .... aN
其中每一个a1
..aN
都是从两个不同的模块导入的。尝试哪种组合类型检查原则上需要测试 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
改为使用,则需要为所有导入的标识符指定模块名称。
推荐阅读
- node.js - 如何使其仅在使用 async await 生成 pdf 后才发送 pdf
- javascript - Service Worker 在大多数移动浏览器中不起作用
- c++ - fabsf 是 C++11 中 std 命名空间的一部分吗?
- mysql - MySql 中的“DECIMAL DEFAULT 0”是什么意思?
- android - 将价值从活动传递到片段
- oracle - 逐页读取Oracle表中的所有数据
- r - 在 r 中添加对 lightgbm 的回调
- python - 如何更新烧瓶中购物车中的数量?
- python - 处理相机旋转的正确方法
- flutter - 如何将文本表单字段下的行扩展到可见性图标下?