2

I've started using Haskell lately, and defined this seemingly simple function:

f 0 = 1
f x = x * f x - 1

However, it results in this:

GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Prelude> f 0 = 1
Prelude> f x = x * f x - 1
Prelude> f 10
*** Exception: stack overflow
Prelude>
5
  • 3
    GHCi doesn't realize you are defining one function f. It proceeds line by line so f x = x * f x - 1 is a function f shadowing the previous definition of f (f 0 = 1). To enter a multiline block, enter :{. Close that block with :}. Commented Oct 5, 2017 at 16:12
  • 1
    stackoverflow.com/questions/8443035/multi-line-commands-in-ghci Commented Oct 5, 2017 at 16:12
  • 3
    You're function definition also defines f x using f x. Your definition means that f x = x * (f x) - 1, not x * (f (x - 1)) Commented Oct 5, 2017 at 16:15
  • @Alec It didn't work: Prelude> :{ Prelude| f 0 = 1 Prelude| f x = x * f x - 1 Prelude| :} Prelude> f 10 *** Exception: stack overflow Prelude> Commented Oct 5, 2017 at 16:16
  • 2
    @MarkNeu Sure it didn't, but not for the same reason. Note that x * f x - 1 gets parsed as (x * f x) - 1. Did you mean x * f (x - 1)? Commented Oct 5, 2017 at 16:18

1 Answer 1

9

Your factorial seems innocent, but it isn't. It's parsed like this:

f 0 = 1
f x = x * (f x) - 1

What happens if we use f 1?

f 1 = 1 * (f 1) - 1 = 1 * (1 * (f 1) - 1) - 1
    = 1 * (1 * (1 * (f 1) - 1) - 1) - 1
    = 1 * (1 * (1 * (1 * (f 1) - 1) - 1) - 1) - 1
    = ...

I'm going to stop here. This will never end. It will build up a stack of parentheses, and at some the whole tower collapses and you end up with a stack overflow.

You have to use parentheses:

f 0 = 1
f x = x * f (x - 1)

Now we get the correct result:

f 1 = 1 * f (1 - 1) = 1 * f 0 = 1 * 1 = 1

Keep in mind that this works only in an implementation file. In GHCi you have to use multi-line mode or a semicolon:

ghci> f 0 = 1; f x = x * f (x - 1)
ghci> -- or
ghci> :{
ghci| f 0 = 0
ghci| f x = x * f (x - 1)
ghci| :}

Otherwise later definitions will shadow earlier ones. Note that your prompt might differ.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.