Haskell ghci用*和max读取行为

时间:2022-11-30 22:33:57

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是不明确的”。