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第一个例子中的 似乎消失了?
似乎未指定的应用上下文被剥离以用于最终评估以打印到输出,但我想知道这的规则是什么。
这是这里简要讨论的 GHCi 特性。当在 GHCi 提示符下输入表达式并求值时,如果其类型可以与 统一IO a,那么它将作为返回类型为 的 IO 操作执行a,并显示该操作的返回值(如果不是 和())如果它有一个Show实例)。
原来 的对应值it会被设置为IO动作的返回值,而不是IO动作本身。我想这个想法是,如果你要写:
> getLine\nI typed this! <-- what I typed\n"I typed this!" <-- the return value displayed\nRun Code Online (Sandbox Code Playgroud)\n您想要it给出返回值,而不是重新运行 IO 操作:
> it\n"I typed this!"\n> :t it\nit :: String\nRun Code Online (Sandbox Code Playgroud)\n具体来说,在您的情况下,表达式的类型:
\n> pure 5 :: Applicative t => t Integer\nRun Code Online (Sandbox Code Playgroud)\n可以与 统一IO Integer,所以也是如此。IO 操作运行,返回值为5,并且它同时成为 的输出和值it。
请注意,如果您编写无法与 IO 统一的表达式,会发生什么情况:
\n> pure 5 :: (Applicative t, Foldable t) => t Integer\n[5]\nRun Code Online (Sandbox Code Playgroud)\n在这里,因为作用域中IO没有Foldable实例,所以类型不能与 统一IO,而是使用 GHCi 的“扩展默认”规则来将类型分配给未指定的类型变量。[]这些扩展规则包括对未知类型使用列表类型* -> *,因此我们得到pure 5 :: [Integer]。如果我们首先添加一个Foldable IO实例,然后再次与 IO 统一,我们就会得到您已经观察到的行为:
> 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\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |