我开始学习haskell并发现自己不得不一次又一次地重新启动repl,因为我为一个函数定义了不正确的特化,我不知道如何删除它们.
例如,假设我将基本案例放在n == 0一般情况下作为阶乘函数的错误:
fact n = n * fact(n-1)
fact 0 = 1
Run Code Online (Sandbox Code Playgroud)
这显然是错误的,现在如果我重复一般情况,它将被添加到当前列表,给我3个重载fact.
如何删除我定义的第一个案例,或者删除所有fact可能的定义.是否可以删除我在GHCI中定义的功能?如果有,怎么样?
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
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
使用GHC,第一个定义将导致堆栈溢出,第二个定义将是正确的.
但是在GHCi中,每个绑定都会影响前一个具有相同名称的绑定.在上面的示例中,在每个会话中,包含等式的每一行fact都是完整的定义.当fact 3被调用时,只有第二行是有效,并且第一个是不可见的.
因此,您无法像在正常GHC中那样定义函数.
要正确定义阶乘函数,可以使用这三种方法之一.
没有布局的支撑定义.
Prelude> let { fact 0 = 1; fact n = n * fact(n-1) }
Run Code Online (Sandbox Code Playgroud)具有特殊GHCi支撑的多线定义.
Prelude> :{
Prelude| let fact 0 = 1
Prelude| fact n = n * fact (n-1)
Prelude| :}
Run Code Online (Sandbox Code Playgroud)没有特殊括号的多线定义(:set +m可以添加到您的需求中~/.ghci)
Prelude> let fact 0 = 1
Ptelude| fact n = n * fact (n-1)
Prelude|
Prelude>
Run Code Online (Sandbox Code Playgroud)有关更多信息,请参阅手册.
注意我已经let在这些定义中使用了,因为我习惯了它们,但实际上它们在较新版本的GHCi中并不是必需的.