GHCi如何打印由“纯”创建的部分应用值? [英] How does GHCi print partially-applied values created from "pure"?
问题描述
我一直在玩弄 Applicative
实例来弄清楚它们是如何工作的。然而,我真的不明白这种行为。
如果我定义了我自己的数据类型,那么应用 pure 来它没有其他参数,没有任何打印输出,但是如果我尝试将结果应用于某个结果,则会出错。
ghci>数据T = A
ghci>纯A
ghci>纯A 0
<互动>:21:1:
使用'print'产生的(Show T)没有实例
在交互式GHCi命令:打印它
但是,如果我使 T
一个显示
的实例,然后在这两种情况下打印出 A
。
ghci>数据T = A派生(显示)
ghci>纯A
A
ghci>纯A 0
A
我真的不明白的是纯A
可以是在两种情况下以不同方式打印的值。是不是纯A
部分应用?
我明白为什么调用纯A 0
第一个例子中的错误,而不是第二个错误 - 这对我很有意义。这是使用 Applicative
的(( - >)r)
实例,因此它只是产生一个总是返回的函数 A
。
但是纯粹
如何仅以当应用本身的类型尚不知道时的一个值?此外,GHC如何可能打印此值?
- 作为
IO
要执行的操作。 - 作为打印输出的值。
由于 IO
是 Applicative
,它正在解释 pure A 作为产生类型
T
的动作的 IO
动作。它执行该操作(不执行任何操作),并且由于结果不在 Show
中,所以不会打印任何内容。如果你让 T
一个显示
的实例,那么它会打印出你的结果。
当您写纯A 0
时,GHCi会看到:
pure :: Applicative f => a - > f a
pure A :: Applicative f => f T
既然您应用纯A
至 0
,纯A
必须是一个函数 a-> b
对于某些类型 a
和 b
和 a
必须包含 0
。
(Num a,Applicative f)= > (请注意, x〜b
$ b $ y
表示 x
和 y
统一 - 可以使它们具有相同的类型。)
因此,我们必须有 f〜(( - >)a)
和 T〜b
,所以实际上GHC推断,在这种情况下,
纯A: :Num a => (( - >)a)T
我们可以重写为
纯A :: Num a => a - > T
好的,( - >)a
是 Applicative
的一个实例,即reader,所以这没关系。当我们将纯A
应用于 0
时,我们得到 T
,即 A
。当然 不能解释为 IO
动作,所以如果 T
不是一个显示
的实例,GHCi会投诉。
I've been playing around with Applicative
instances in order to figure out how they work. However, I honestly don't understand this behavior.
If I define my own datatype, then apply pure
to it with no other arguments, nothing prints out, but it errors if I try to apply something to the result.
ghci> data T = A
ghci> pure A
ghci> pure A 0
<interactive>:21:1:
No instance for (Show T) arising from a use of ‘print’
In a stmt of an interactive GHCi command: print it
However, if I make T
an instance of Show
, then A
is printed out in both cases.
ghci> data T = A deriving (Show)
ghci> pure A
A
ghci> pure A 0
A
What I really don't understand is how pure A
can be a value that is printed differently between the two cases. Isn't pure A
partially applied?
I do understand why calling pure A 0
errors in the first example and doesn't in the second—that makes sense to me. That's using the ((->) r)
instance of Applicative
, so it simply yields a function that always returns A
.
But how is pure
instantiated with only one value when the type of the applicative itself isn't yet known? Furthermore, how can GHC possibly print this value?
解决方案 GHCi is a little bit peculiar. In particular, when you type an expression at the prompt, it tries to interpret it in two different ways, in order:
- As an
IO
action to execute.
- As a value to print out.
Since IO
is Applicative
, it is interpreting pure A
as an IO
action producing something of type T
. It executes that action (which does nothing), and since the result is not in Show
, it does not print anything out. If you make T
an instance of Show
, then it kindly prints out the result for you.
When you write pure A 0
, GHCi sees this:
pure :: Applicative f => a -> f a
pure A :: Applicative f => f T
And since you apply pure A
to 0
, pure A
must be a function a->b
for some types a
and b
, and a
must contain 0
.
(Num a, Applicative f) => f T ~ (a -> b)
(Note that x ~ y
means that x
and y
unify—they can be made to have the same type.)
Thus we must have f ~ ((->) a)
and T ~ b
, so in fact GHC infers that, in this context,
pure A :: Num a => ((->) a) T
Which we can rewrite as
pure A :: Num a => a -> T
Well, (->) a
is an instance of Applicative
, namely "reader", so this is okay. When we apply pure A
to 0
we get something of type T
, namely A
. This cannot be interpreted as an IO
action, of course, so if T
is not an instance of Show
, GHCi will complain.
这篇关于GHCi如何打印由“纯”创建的部分应用值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!