Function definition by special cases in GHCi

核能气质少年 提交于 2019-12-17 07:52:13

问题


From a Haskell tutorial:

We can write functions on integers by cases.

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

However, here's what happens when I try it:

$ 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

What am I missing?


回答1:


To use your definition in GHCi exactly as you wrote it (i.e. with multiple equations in separate lines), you need to use multiline input in GHCi through the :{ and :} delimiters:

GHCi> :{
GHCi| foo 0 = print 999
GHCi| foo n = print n
GHCi| :}
GHCi> foo 0
999

One alternative would be turing on multiline input for the rest of your session with the +m option. In this case, though, you also need an explicit let, as without it GHCi won't figure out you want to continue the definition:

GHCi> :set +m
GHCi> let foo 0 = print 999
GHCi|     foo n = print n
GHCi| 
GHCi> foo 0
999

(You can turn +m off with :unset +m.)

Yet another possibility is eschewing line breaks altogether, and using explicit braces and semicolons:

GHCi> foo 0 = print 999; foo n = print n
GHCi> foo 0
999

Between the multiline options, I personally prefer the explicit delimiters over +m, as it requires less changes with respect to how I usually phrase my definitions, and is more likely to work straight away if I paste code from somewhere else.

As for why your way of entering it didn't work, it was because, unless you use multiline input, bindings to the same name in separate GHCi lines shadow each other:

GHCi> x = 3
GHCi> x = 4
GHCi> x
4

This seems less surprising if we note that we get the same behaviour from a chain of let-expressions:

GHCi> let x = 3 in let x = 4 in x
4



回答2:


ghci is an interactive tool and as such allows to redefine a function when it's already be define. In your case, it doesn't see it as a two lines function definition but as two attempts of defining it. So f n = print n overrides f 0 = print 999 instead of completing it.

To enter multiple lines statement in ghci there is a special syntax. You need to do

Prelude> :{
Prelude> let foo 0 = print 999
Prelude>     foo n = print n
Prelude> :}


来源:https://stackoverflow.com/questions/42593284/function-definition-by-special-cases-in-ghci

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!