func = elem [1..10] 在 GHCi 中工作但不编译
func = elem [1..10] works in GHCi but doesn't compile
在 GHCi 中 运行 这个命令
func = elem [1..10]
工作正常,并返回了部分功能。我很好奇为什么它有效?当我尝试编译这段代码时,它给了我一个错误。例如,这不适用于其他功能。 Map 在 GHCi 和编译时给我一个错误。
func = map [1..10]
想知道 GHCi 和函数 elem 有什么特别之处。
我知道我可以这样写:
func = (`elem` [1..10])
func = (`map` [1..10])
它有效,但为什么其他方法对 elem 有效。
elem [1..10]
是一个非常明智的术语。示例:
Prelude> elem [1..10] [[0..9], [1..10]]
True
Prelude> elem [1..10] [[0..8], [1..7]]
False
也许更常见的是这样写
Prelude> [1..10] `elem` [[0..9], [1..10]]
True
Prelude> [1..10] `elem` [[0..8], [1..7]]
False
但这只是同一事物的不同语法版本。
这也意味着它 可以 被编译,你只需要给它一个合适的签名(或者让 GHC 为你推断一个)。例如,
f :: [[Int]] -> Bool
f = elem [1..10]
...它是告诉您数字列表列表是否包含列表 [1..10]
的函数。 IE。与 elem
的任何其他用法一样,它会告诉您某个列表是否包含某个元素。这个元素恰好本身就是一个列表这一事实是无关紧要的。
另一方面 map [1..10]
是错误的,因为 map
的第一个参数必须是 函数 。列表虽然可以是列表元素,但永远不能是函数†.
运算符部分 (`elem`[1..10])
和 (`map`[1..10])
则完全不同。在这些示例中,[1..10]
实际上是 second 参数。该部分省略了 left/first 参数。所以在这种情况下,我们所说的是
Prelude> 3 `elem` [1..10]
True
Prelude> 19 `elem` [1..10]
False
...这也适用于
Prelude> negate `map` [1..10]
[-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
尽管更常见的写法是 map negate [1..10]
或 negate<$>[1..10]
。
†从某种意义上说,既迂腐又无政府主义,列表 实际上可以是函数:用 -XOverloadedLists
扩展名,您可以编写一个 class-实例,允许您使用列表语法定义函数。我看不出这有什么意义,但了解这种理论上的可能性也许是件好事。特别是,启用该扩展后,map [1..10]
令人困惑地 确实 编译,你只会在其他地方得到一个涉及 Could not deduce
... The type variable ‘a0’ is ambiguous
乱码的令人困惑的错误.
在 GHCi 中 运行 这个命令
func = elem [1..10]
工作正常,并返回了部分功能。我很好奇为什么它有效?当我尝试编译这段代码时,它给了我一个错误。例如,这不适用于其他功能。 Map 在 GHCi 和编译时给我一个错误。
func = map [1..10]
想知道 GHCi 和函数 elem 有什么特别之处。
我知道我可以这样写:
func = (`elem` [1..10])
func = (`map` [1..10])
它有效,但为什么其他方法对 elem 有效。
elem [1..10]
是一个非常明智的术语。示例:
Prelude> elem [1..10] [[0..9], [1..10]]
True
Prelude> elem [1..10] [[0..8], [1..7]]
False
也许更常见的是这样写
Prelude> [1..10] `elem` [[0..9], [1..10]]
True
Prelude> [1..10] `elem` [[0..8], [1..7]]
False
但这只是同一事物的不同语法版本。
这也意味着它 可以 被编译,你只需要给它一个合适的签名(或者让 GHC 为你推断一个)。例如,
f :: [[Int]] -> Bool
f = elem [1..10]
...它是告诉您数字列表列表是否包含列表 [1..10]
的函数。 IE。与 elem
的任何其他用法一样,它会告诉您某个列表是否包含某个元素。这个元素恰好本身就是一个列表这一事实是无关紧要的。
另一方面 map [1..10]
是错误的,因为 map
的第一个参数必须是 函数 。列表虽然可以是列表元素,但永远不能是函数†.
运算符部分 (`elem`[1..10])
和 (`map`[1..10])
则完全不同。在这些示例中,[1..10]
实际上是 second 参数。该部分省略了 left/first 参数。所以在这种情况下,我们所说的是
Prelude> 3 `elem` [1..10]
True
Prelude> 19 `elem` [1..10]
False
...这也适用于
Prelude> negate `map` [1..10]
[-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
尽管更常见的写法是 map negate [1..10]
或 negate<$>[1..10]
。
†从某种意义上说,既迂腐又无政府主义,列表 实际上可以是函数:用 -XOverloadedLists
扩展名,您可以编写一个 class-实例,允许您使用列表语法定义函数。我看不出这有什么意义,但了解这种理论上的可能性也许是件好事。特别是,启用该扩展后,map [1..10]
令人困惑地 确实 编译,你只会在其他地方得到一个涉及 Could not deduce
... The type variable ‘a0’ is ambiguous
乱码的令人困惑的错误.