我开始学习haskell,发现自己不得不一次又一次地重新启动repl,因为我为某个函数定义了错误的专业名称,而且我不知道如何删除它们。
例如,假设我犯了一个错误:将n == 0
的基本情况放在阶乘函数的一般情况之后:
fact n = n * fact(n-1)
fact 0 = 1
这显然是错误的,现在,如果我重复一般情况,它将被添加到当前列表中,给我fact
带来了3个重载。
如何删除我定义的第一种情况,或者删除fact
的所有定义。是否可以删除我在GHCI中定义的功能?如果是,怎么办?
答案 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中相同的方式定义函数。
要正确定义阶乘函数,可以使用以下三种方法之一。
无布局的括号定义。
Prelude> let { fact 0 = 1; fact n = n * fact(n-1) }
带有特殊GHCi大括号的多行定义。
Prelude> :{
Prelude| let fact 0 = 1
Prelude| fact n = n * fact (n-1)
Prelude| :}
没有特殊花括号的多行定义(需要:set +m
,可以添加到您的~/.ghci
中)
Prelude> let fact 0 = 1
Ptelude| fact n = n * fact (n-1)
Prelude|
Prelude>
有关更多信息,请参见manual。
请注意,我在这些定义中使用了let
,因为我已经习惯了它们,但实际上在新版本的GHCi中没有必要使用它们。