推导这种类型时,“了解Haskell”中的假设是什么?


18

这个问题不是主观的。参考书中使用了一个非常具体的动词,我想了解该措词的含义,因为恐怕我误会了某些东西。

从“ 了解您的Haskell”中,以下段落是包含“我们假设*” 的第三段也是最后一段。

data Barry t k p = Barry { yabba :: p, dabba :: t k }  

现在我们要使其成为的实例FunctorFunctor想要那种类型,* -> *Barry看起来不像那种类型。是什么样的Barry?好吧,我们看到它需要三个类型参数,因此它将是something -> something -> something -> *。可以肯定地说这p是一种具体类型,因此具有一种*因为k,我们假设*等等,t因此具有一种* -> *。现在,让something我们用用作占位符的替换这些类型,我们看到它有一种(* -> *) -> * -> * -> *

我们为什么要承担一切呢?读完“我们假设X(即我们假设X为真)”后,我自然认为我们也应该考虑X为假的情况。在这个例子中的具体情况,不能t是那种(* -> *) -> *k那种(* -> *)?如果是这样,无论是什么tk实际上是什么,t k仍将是一个具体类型,不是吗?

我看到整个推理过程随后都针对编译器进行了检查,但我认为编译器不假定。如果可以,我想知道,如果不知道,恐怕会丢失该段的含义。


4
你是对的。事实上,我们可以k :: L为任何类型的L,只要t :: L -> *。但是L,这里的编译器必须选择一些特定的,或者诉诸于多种类。多种是最通用的选择,但是GHC在这里选择L = *(基本的Haskell没有多种,必须将它们作为扩展打开)。由于LYAH选择的是相当随意的东西,因此LYAH使用“假定”(AFAICT)一词。

1
好的,也许编译器认为困扰我至少比我们假设少,或者根本不困扰我。
Enrico Maria De Angelis

Answers:


19

实际上,编译器确实假设!但是您可以通过PolyKinds扩展程序来要求它。您可以在此处详细了解它。启用该扩展名后,Barry将为forall k. (k -> *) -> k -> * -> *


-1

好点子。作者做了一个不必要的假设。也许只是为了使他在Type Foo一章中更容易理解,但是像您这样的人可能理所当然地对此表示怀疑。

两者 tk并且p是类型变量。从中yabba :: p我们可以看到它可以单独存在,因此它就像一个常量函数,就好像它是一个值而不是一个类型一样,它的类型签名会说IntChar,无论如何命名。但是由于它是一种类型,所以它的种类签名为*

然而t在此输入需要一个类型变量k构造类型(dabba :: t k,所以我们相信,(在这里没有assumtion)t有一种类似的签名* -> *k*

一旦我们知道了……类型Barry t k p的种类签名就是(* -> *) -> * -> * -> *意味着它需要t然后kp为我们提供Barry类型。

编辑确保阅读下面的@luqui注释。


7
k并不被限制为*如您声称的那样t。例如,我们可以有k :: * -> *t :: (* -> *) -> *doo :: k Int在记录中添加一个字段,它将顺利通过。
luqui

@luqui ..是的,您是正确的...我不会删除此答案,因为您的评论确实值得保留。
Redu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.