GHCi如何打印由“纯”创建的部分应用值? [英] How does GHCi print partially-applied values created from "pure"?

查看:137
本文介绍了GHCi如何打印由“纯”创建的部分应用值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩弄 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如何可能打印此值?

GHCi有点奇特。特别是,当你在提示符下键入一个表达式时,它会尝试以两种不同的方式解释它,依次为:


  1. 作为 IO 要执行的操作。

  2. 作为打印输出的值。

由于 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:

  1. As an IO action to execute.
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆