为什么会导致GHCI挂起?

时间:2015-05-10 11:32:50

标签: haskell ghci

此代码:

y :: Int
y = y + 1

执行时会导致GHCI挂起。

y :: Int; this means y is of type Int
y = y + 1; this means y is defined to be an Int + 1

如果我对陈述的定义不正确,请纠正我。

为什么不评估?

是否正在将y添加到Int中,但它只是被添加到某个类型而不是值?

2 个答案:

答案 0 :(得分:4)

那是因为它无限地递归。您正在调用y,其定义为y + 1。那么评估将如何进行呢?

它是这样的:

y
y + 1
(y + 1) + 1
((y + 1) + 1) + 1

依旧......

答案 1 :(得分:3)

更广泛地说,Haskell文件(或GHCi)不包含命令/命令列表,就像其他一些编程语言一样。它是一种不同风格的编程语言。相反,您可以访问以下几种顶级语句:

  1. 您可以定义值。 y = y + 1将符号y定义为函数(+)应用于其他两个参数y1。此定义在整个文件中包含,特别是上面的定义定义中的。因此,您可以在y = x + 1文件中完整地写x = 2然后.hs,并向GHCi询问y,它会说3。请注意,使用let关键字会变得更复杂,这会形成一个"墙"定义的这种广泛性:let接受一个定义块和一个值表达式,并将这些定义范围限定在组合(定义块,值表达式)上下文中,但是从这些定义中除去那些定义。 let之外的世界。所以这也是有效的:

    Prelude> let y = x + 1; x = 2
    Prelude> y
    3
    
  2. 您可以定义数据结构及其构造函数。构造函数是一个特殊的函数,我们允许它参与模式匹配:换句话说,Haskell知道如何反转 destructure 每个构造函数。您还可以定义type同义词和newtype,它们介于两者之间。

  3. 您可以提供有关各个值(类型声明)的元数据。这些对于缩小类型错误的位置非常有帮助,因为它们设置了一个" wall"对于类型推断算法。它们还可以在添加多态性(Haskell具有"单态限制"经常咬新手)或将多态性限制为具体类型时具有语义效果。

  4. 您可以提供有关整个软件包的元数据:它如何包含其他软件包(import语句)以及其他软件包如何使用它们(模块语句)。

  5. 这些都不是你给Haskell系统的订单;相反,您的文件是模块的所有大描述。类似地,在表达式(上面的第一部分)中,您只能做一些事情,而且它们通常不是必需的:您可以将值应用于其他值,创建函数,您可以创建本地定义(let )和模式匹配(case),您可以在本地添加类型元数据。其他所有内容,包括do符号,只是一种更方便的方法("语法糖")来完成上述事情。

    你的两个语句是一个类型声明("这个模块定义的y的类型将是一个整数")和一个定义("来计算{{1根据此模块的定义,首先计算y的值,然后向其中添加一个")。 Haskell一起读取它们并且说,"哦,y具有类型y,所以Int是我所知道的特定Int-Plus操作,(+) ,然后(+) :: Int -> Int -> Int是我知道的那个名字的具体1。然后它将确认类型是自洽的,并产生一些永远循环的命令性代码。