删除GHCI中定义的功能

时间:2018-11-30 06:06:51

标签: haskell ghci

我开始学习haskell,发现自己不得不一次又一次地重新启动repl,因为我为某个函数定义了错误的专业名称,而且我不知道如何删除它们。

例如,假设我犯了一个错误:将n == 0的基本情况放在阶乘函数的一般情况之后:

fact n = n * fact(n-1)
fact 0 = 1

这显然是错误的,现在,如果我重复一般情况,它将被添加到当前列表中,给我fact带来了3个重载。

如何删除我定义的第一种情况,或者删除fact的所有定义。是否可以删除我在GHCI中定义的功能?如果是,怎么办?

1 个答案:

答案 0 :(得分:5)

Prelude> fact n = n * fact (n-1)
Prelude> fact 0 = 1
Prelude> fact 3
*** Exception: <interactive>:6:1-10: Non-exhaustive patterns in function fact
Prelude> :q
Leaving GHCi.
bash> ghci
Prelude> fact 0 = 1
Prelude> fact n = n * fact (n-1)
Prelude> fact 3
*** Exception: stack overflow

这是怎么回事?

使用GHC,第一个定义将导致堆栈溢出,第二个定义将是正确的。

但是在GHCi中,每个绑定阴影都具有相同的名称。在上面的示例中,在每个会话中,包含fact的等式的每一行都是完整定义。调用fact 3时,只有第二行有效,而第一行不可见。

因此,您不能以与普通GHC中相同的方式定义函数。

要正确定义阶乘函数,可以使用以下三种方法之一。

  1. 无布局的括号定义。

    Prelude> let { fact 0 = 1; fact n = n * fact(n-1) }
    
  2. 带有特殊GHCi大括号的多行定义。

    Prelude> :{
    Prelude| let fact 0 = 1
    Prelude|     fact n = n * fact (n-1)
    Prelude| :}
    
  3. 没有特殊花括号的多行定义(需要:set +m,可以添加到您的~/.ghci中)

    Prelude> let fact 0 = 1 
    Ptelude|     fact n = n * fact (n-1)
    Prelude|
    Prelude>
    

有关更多信息,请参见manual

请注意,我在这些定义中使用了let,因为我已经习惯了它们,但实际上在新版本的GHCi中没有必要使用它们。