功能定义由GHCi中的特殊情况

Vor*_*rac 8 haskell ghci

从Haskell 教程:

我们可以根据情况编写整数函数.

-- Compute the sum of the integers from 1 to n.
sumtorial :: Integer -> Integer
sumtorial 0 = 0
sumtorial n = n + sumtorial (n-1)
Run Code Online (Sandbox Code Playgroud)

但是,这是我尝试时会发生的事情:

$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
Prelude> foo 0 = print 999
Prelude> foo n = print n
Prelude> foo 0
0
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

dup*_*ode 17

要在GHCi中完全按照您的定义使用您的定义(即在单独的行中使用多个等式),您需要通过:{:}分隔符在GHCi中使用多行输入:

GHCi> :{
GHCi| foo 0 = print 999
GHCi| foo n = print n
GHCi| :}
GHCi> foo 0
999
Run Code Online (Sandbox Code Playgroud)

一种替代方案是使用该+m选项在会话的其余部分上进行多行输入.但是在这种情况下,你还需要一个显式的let,因为没有它,GHCi不会想出你想要继续定义:

GHCi> :set +m
GHCi> let foo 0 = print 999
GHCi|     foo n = print n
GHCi| 
GHCi> foo 0
999
Run Code Online (Sandbox Code Playgroud)

(你可以+m关掉:unset +m.)

另一种可能性是完全避免换行,并使用显式括号和分号:

GHCi> foo 0 = print 999; foo n = print n
GHCi> foo 0
999
Run Code Online (Sandbox Code Playgroud)

在多行选项之间,我个人更喜欢明确的分隔符+m,因为它对我通常如何定义我的定义所需的更少变化,如果我从其他地方粘贴代码,则更有可能立即工作.

至于为什么你输入它的方式不起作用,这是因为,除非你使用多行输入,否则在单独的GHCi行中绑定到相同名称会相互影响:

GHCi> x = 3
GHCi> x = 4
GHCi> x
4
Run Code Online (Sandbox Code Playgroud)

如果我们注意到从let表达链中获得相同的行为,这似乎就不那么令人惊讶了:

GHCi> let x = 3 in let x = 4 in x
4
Run Code Online (Sandbox Code Playgroud)


mb1*_*b14 5

ghci是一个交互式工具,因此可以在定义函数时重新定义它。在您的情况下,它不是将其视为两行函数定义,而是将其视为两次定义它的尝试。因此f n = print n覆盖f 0 = print 999而不是完成它。

要在ghci中输入多行语句,有一种特殊的语法。你需要做

Prelude> :{
Prelude> let foo 0 = print 999
Prelude>     foo n = print n
Prelude> :}
Run Code Online (Sandbox Code Playgroud)