I have the following function defined:
ex 1 x = 1
ex 0 x = 0
ex b x = b ** x
Then, when I execute the following:
1 `ex` (sum [1..])
it tries to calculate the sum of the infinite sequence, instead of being lazy and returning 1. Why?
EDIT: Upon further investigation, I found that laziness happens if I define the ex
function in a file, but not if I define it in GHCI:
$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> let ex 1 x = 1
Prelude> let ex b x = b ** x
Prelude> ex 1 (sum [1..])
<interactive>: out of memory (requested 1048576 bytes)
If I pull the ex
definition into a file (in this case, test.hs):
$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> :load test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> ex 1 (sum [1..])
1.0
The new question, then, is why?
In GHCi, each let
statement introduces a new definition of ex
, instead of multiple pattern cases as you expect. So it hangs because, when you enter ex 1 (sum [1..])
afterwards, only the final ex b x = b ** x
version exists.
If you want to define a function with multiple pattern cases in GHCi, you'll need to put it in a single let
statement, like this:
let ex 1 x = 1; ex 0 x = 0; ex b x = b ** x
The same applies for anything else that would normally be written across multiple lines, such as do
notation. For instance, a function like this:
f x = do
y <- get
put (x + y)
return y
Would have to be written like this in GHCi:
let f x = do { y <- get; put (x + y); return y }
Prelude> let ex 1 x = 1
Prelude> let ex b x = b ** x
You're not defining a function with two cases here. You define a function with one case, and then you define it again overriding the previous definition.
To define one function with two patterns use let ex 1 x = 1; ex b x = b ** x
, i.e. separate the cases with a semicolon.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With