消失的应用程序?
Disappearing applicative?
在未指定 Applicative 实例的情况下,我对 pure
的行为有点困惑。在此示例中,我希望结果值为应用上下文中的数字 5:
Prelude> pure 5 :: Applicative t => t Integer
5
Prelude> :t it
it :: Integer
相反,它只是一个普通的整数。
如果指定了应用实例,如下例所示,返回值是应用类型,如我所料:
Prelude> pure 5 :: Maybe Integer
Just 5
Prelude> :t it
it :: Maybe Integer
为什么 Applicative t
在第一个示例中似乎消失了?
似乎正在剥离未指定的应用上下文以进行最终评估以打印到输出,但我想知道这方面的规则是什么。
这是简要讨论过的 GHCi 特性 here。当在 GHCi 提示符下输入表达式并求值时,如果它的类型可以与 IO a
统一,那么它将作为一个 IO 动作执行 return 类型 a
,并且 return 将显示操作的值(如果它不是 ()
并且它有一个 Show
实例)。
原来it
对应的值会被设置为IO action的return值,而不是IO action本身。我想这个想法是,如果你要写:
> getLine
I typed this! <-- what I typed
"I typed this!" <-- the return value displayed
您希望 it
给出 returned 值,而不是 re-run IO 操作:
> it
"I typed this!"
> :t it
it :: String
具体来说,在您的情况下,表达式的类型:
> pure 5 :: Applicative t => t Integer
可以和IO Integer
统一,原来如此。 IO 操作是 运行,return 值是 5
,它成为 it
.
的输出和值
注意如果你写了一个不能与 IO 统一的表达式会发生什么:
> pure 5 :: (Applicative t, Foldable t) => t Integer
[5]
这里,因为IO
在范围内没有Foldable
实例,类型不能与IO
统一,取而代之的是GHCi的“扩展默认”规则,用于将类型分配给未指定的使用类型变量。这些扩展规则包括对未知类型 * -> *
使用列表类型 []
,因此我们得到 pure 5 :: [Integer]
。如果我们首先添加一个 Foldable IO
实例,然后与 IO 的统一再次起作用,我们得到您已经观察到的行为:
> instance Foldable IO -- this works, despite the warning
<interactive>:11:10: warning: [-Wmissing-methods]
• No explicit implementation for
either ‘foldMap’ or ‘foldr’
• In the instance declaration for ‘Foldable IO’
> pure 5 :: (Applicative m, Foldable m) => m Integer
5
在未指定 Applicative 实例的情况下,我对 pure
的行为有点困惑。在此示例中,我希望结果值为应用上下文中的数字 5:
Prelude> pure 5 :: Applicative t => t Integer
5
Prelude> :t it
it :: Integer
相反,它只是一个普通的整数。
如果指定了应用实例,如下例所示,返回值是应用类型,如我所料:
Prelude> pure 5 :: Maybe Integer
Just 5
Prelude> :t it
it :: Maybe Integer
为什么 Applicative t
在第一个示例中似乎消失了?
似乎正在剥离未指定的应用上下文以进行最终评估以打印到输出,但我想知道这方面的规则是什么。
这是简要讨论过的 GHCi 特性 here。当在 GHCi 提示符下输入表达式并求值时,如果它的类型可以与 IO a
统一,那么它将作为一个 IO 动作执行 return 类型 a
,并且 return 将显示操作的值(如果它不是 ()
并且它有一个 Show
实例)。
原来it
对应的值会被设置为IO action的return值,而不是IO action本身。我想这个想法是,如果你要写:
> getLine
I typed this! <-- what I typed
"I typed this!" <-- the return value displayed
您希望 it
给出 returned 值,而不是 re-run IO 操作:
> it
"I typed this!"
> :t it
it :: String
具体来说,在您的情况下,表达式的类型:
> pure 5 :: Applicative t => t Integer
可以和IO Integer
统一,原来如此。 IO 操作是 运行,return 值是 5
,它成为 it
.
注意如果你写了一个不能与 IO 统一的表达式会发生什么:
> pure 5 :: (Applicative t, Foldable t) => t Integer
[5]
这里,因为IO
在范围内没有Foldable
实例,类型不能与IO
统一,取而代之的是GHCi的“扩展默认”规则,用于将类型分配给未指定的使用类型变量。这些扩展规则包括对未知类型 * -> *
使用列表类型 []
,因此我们得到 pure 5 :: [Integer]
。如果我们首先添加一个 Foldable IO
实例,然后与 IO 的统一再次起作用,我们得到您已经观察到的行为:
> instance Foldable IO -- this works, despite the warning
<interactive>:11:10: warning: [-Wmissing-methods]
• No explicit implementation for
either ‘foldMap’ or ‘foldr’
• In the instance declaration for ‘Foldable IO’
> pure 5 :: (Applicative m, Foldable m) => m Integer
5