【问题标题】:ghci special case for Applicative?Applicative 的 ghci 特例?
【发布时间】:2011-12-18 11:11:14
【问题描述】:

在 ghci 中:

λ> :t (pure 1)
(pure 1) :: (Applicative f, Num a) => f a
λ> show (pure 1)

<interactive>:1:1:
    No instance for (Show (f0 a0))
      arising from a use of `show'
    Possible fix: add an instance declaration for (Show (f0 a0))
    In the expression: show (pure 1)
    In an equation for `it': it = show (pure 1)
λ> pure 1
1

这是否意味着ghci执行Applicative并显示结果,就像IO一样?

请注意,pure ()pure (+1) 不会打印任何内容。

【问题讨论】:

  • show (pure 1 :: [Int]) 有效。 show (pure 1 :: Maybe Integer) 也是。那里没有默认设置,所以 ghci 不知道选择哪种类型。

标签: haskell monads ghci applicative


【解决方案1】:

如果您使用return 而不是pure,您将获得相同的行为。要找出要做什么,ghci 必须为给定的表达式选择一个类型。 ghci 的默认规则是在没有其他约束的情况下,它选择IO 作为ApplicativeMonad 实例。因此它将pure 1 解释为IO Integer 类型的表达式。如果 1.a 具有 Show 实例且 2.a 不是 (),则在提示符处输入的 IO a 类型的表达式将被执行并打印其结果。因此在提示符处输入pure 1会导致

v <- return (1 :: Integer)
print v
return v

正在执行(并且魔术变量it 绑定到返回的v)。对于pure (),特殊情况适用,因为()被认为是无趣的,因此只执行return ()并且it绑定到(),对于pure (+1),返回一个函数,没有Show实例对于范围内的函数,因此不会打印任何内容。然而,

Prelude Control.Applicative> :m +Text.Show.Functions
Prelude Control.Applicative Text.Show.Functions> pure (+1)
<function>
it :: Integer -> Integer
Prelude Control.Applicative Text.Show.Functions> it 3
4
it :: Integer

对于范围内的函数使用Show 实例,它会被打印(不是提供信息),然后可以使用该函数(当然,后者独立于范围内的Show 实例)。

【讨论】:

  • 我刚刚意识到instance Applicative IO。所以它也允许pure 1 &gt;&gt;= \it -&gt; print it 工作。我刚刚了解了Text.Show.Functions 模块。我一直想知道为什么函数默认不显示。
  • 这里是另一个使用 Applicative、Functor 和 IO 的例子:pure (+1) &lt;*&gt; fmap (read :: String -&gt; Int) getLine
  • 对于自定义类型类的类型,是否可以指示 ghci 应该默认的类型?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
相关资源
最近更新 更多