应用消失?

Ton*_*nyM 3 haskell ghci

pure我对其 Applicative 实例未指定的情况下的行为有点困惑。在此示例中,我希望在应用上下文中结果值为数字 5:

Prelude> pure 5 :: Applicative t => t Integer
5
Prelude> :t it
it :: Integer
Run Code Online (Sandbox Code Playgroud)

相反,它只是一个普通的整数。

如果指定了应用实例,如以下示例所示,则返回的值是应用类型,正如我所期望的:

Prelude> pure 5 :: Maybe Integer
Just 5
Prelude> :t it
it :: Maybe Integer
Run Code Online (Sandbox Code Playgroud)

为什么Applicative t第一个例子中的 似乎消失了?

似乎未指定的应用上下文被剥离以用于最终评估以打印到输出,但我想知道这的规则是什么。

K. *_*uhr 6

这是这里简要讨论的 GHCi 特性。当在 GHCi 提示符下输入表达式并求值时,如果其类型可以与 统一IO a,那么它将作为返回类型为 的 IO 操作执行a,并显示该操作的返回值(如果不是 和())如果它有一个Show实例)。

\n

原来 的对应值it会被设置为IO动作的返回值,而不是IO动作本身。我想这个想法是,如果你要写:

\n
> getLine\nI typed this!    <-- what I typed\n"I typed this!"  <-- the return value displayed\n
Run Code Online (Sandbox Code Playgroud)\n

您想要it给出返回值,而不是重新运行 IO 操作:

\n
> it\n"I typed this!"\n> :t it\nit :: String\n
Run Code Online (Sandbox Code Playgroud)\n

具体来说,在您的情况下,表达式的类型:

\n
> pure 5 :: Applicative t => t Integer\n
Run Code Online (Sandbox Code Playgroud)\n

可以与 统一IO Integer,所以也是如此。IO 操作运行,返回值为5,并且它同时成为 的输出和值it。

\n

请注意,如果您编写无法与 IO 统一的表达式,会发生什么情况:

\n
> pure 5 :: (Applicative t, Foldable t) => t Integer\n[5]\n
Run Code Online (Sandbox Code Playgroud)\n

在这里,因为作用域中IO没有Foldable实例,所以类型不能与 统一IO,而是使用 GHCi 的“扩展默认”规则来将类型分配给未指定的类型变量。[]这些扩展规则包括对未知类型使用列表类型* -> *,因此我们得到pure 5 :: [Integer]。如果我们首先添加一个Foldable IO实例,然后再次与 IO 统一,我们就会得到您已经观察到的行为:

\n
> instance Foldable IO   -- this works, despite the warning\n\n<interactive>:11:10: warning: [-Wmissing-methods]\n    \xe2\x80\xa2 No explicit implementation for\n        either \xe2\x80\x98foldMap\xe2\x80\x99 or \xe2\x80\x98foldr\xe2\x80\x99\n    \xe2\x80\xa2 In the instance declaration for \xe2\x80\x98Foldable IO\xe2\x80\x99\n> pure 5 :: (Applicative m, Foldable m) => m Integer\n5\n
Run Code Online (Sandbox Code Playgroud)\n