So I've just encountered the following in ghci:
所以我刚刚在ghci中遇到了以下内容:
(*) (read "10") (read "20")
returns 200 as expected. However, this line
按预期返回200。但是,这一行
(max) (read "10") (read "20")
throws an exception:
抛出异常:
*** Exception: Prelude.read: no parse
And I can't really figure out the cause for such ghci behaviour. Any help would be appreciated!
我无法弄清楚这种ghci行为的原因。任何帮助,将不胜感激!
1 个解决方案
#1
This is an instance of GHCi’s defaulting rules. When it encounters an ambiguous type, it selects ()
(“unit”) as the default. So it’s attempting to read 10
as a value of type ()
, which fails to parse.
这是GHCi违约规则的一个例子。当遇到不明确的类型时,它会选择()(“unit”)作为默认值。所以它试图将10作为type()的值来读取,该值无法解析。
The type is ambiguous because read
’s return type is overloaded to work on any instance of Read
, and max
’s parameter type is overloaded to work on any instance of Ord
, so the compiler doesn’t have any way to know which type you intended for the intermediate values:
类型是不明确的,因为read的返回类型被重载以在任何Read实例上工作,并且max的参数类型被重载以在Ord的任何实例上工作,因此编译器无法知道您打算用于中间体的类型值:
read :: (Read a) => String -> a
max :: (Ord a) => a -> a -> a
You will also see this behaviour if you simply write this:
如果你只是写这个,你也会看到这种行为:
read "10"
But writing this will work:
但写这个将工作:
read "()"
One solution is to give an explicit type annotation:
一种解决方案是提供显式类型注释:
max (read "10" :: Int) (read "20" :: Int)
This returns 20
as expected.
这将按预期返回20。
You can also disable this behaviour with a command-line flag:
您还可以使用命令行标志禁用此行为:
ghci -XNoExtendedDefaultRules
Or with a GHCi command:
或者使用GHCi命令:
:set -XNoExtendedDefaultRules
And then you will get an appropriate error message along the lines of “No instance for Ord a0
…the type variable a0
is ambiguous”.
然后,您将得到一条相应的错误消息:“没有Ord a0的实例......类型变量a0是不明确的”。
#1
This is an instance of GHCi’s defaulting rules. When it encounters an ambiguous type, it selects ()
(“unit”) as the default. So it’s attempting to read 10
as a value of type ()
, which fails to parse.
这是GHCi违约规则的一个例子。当遇到不明确的类型时,它会选择()(“unit”)作为默认值。所以它试图将10作为type()的值来读取,该值无法解析。
The type is ambiguous because read
’s return type is overloaded to work on any instance of Read
, and max
’s parameter type is overloaded to work on any instance of Ord
, so the compiler doesn’t have any way to know which type you intended for the intermediate values:
类型是不明确的,因为read的返回类型被重载以在任何Read实例上工作,并且max的参数类型被重载以在Ord的任何实例上工作,因此编译器无法知道您打算用于中间体的类型值:
read :: (Read a) => String -> a
max :: (Ord a) => a -> a -> a
You will also see this behaviour if you simply write this:
如果你只是写这个,你也会看到这种行为:
read "10"
But writing this will work:
但写这个将工作:
read "()"
One solution is to give an explicit type annotation:
一种解决方案是提供显式类型注释:
max (read "10" :: Int) (read "20" :: Int)
This returns 20
as expected.
这将按预期返回20。
You can also disable this behaviour with a command-line flag:
您还可以使用命令行标志禁用此行为:
ghci -XNoExtendedDefaultRules
Or with a GHCi command:
或者使用GHCi命令:
:set -XNoExtendedDefaultRules
And then you will get an appropriate error message along the lines of “No instance for Ord a0
…the type variable a0
is ambiguous”.
然后,您将得到一条相应的错误消息:“没有Ord a0的实例......类型变量a0是不明确的”。