Sudantha
Sudantha

Reputation: 16214

Functions in Haskell

I'm new to functional programming. I have a basic question.

I'm using the Hugs interpreter,

I would like to write a function in Haskell; I went though several tutorials, but I'm not getting it.

fact :: Int -> Int
fact n = if n == 0 then
1
else
n * fact (n-1)

This gives me a syntax error :-S

ERROR - Syntax error in input (unexpected `=')

Upvotes: 3

Views: 2495

Answers (4)

Landei
Landei

Reputation: 54584

It should be mentioned that the most elegant way to write this function is:

fac n = product [1..n]

See http://www.willamette.edu/~fruehr/haskell/evolution.html for details.

Upvotes: 1

Dan Burton
Dan Burton

Reputation: 53705

Create a file named, for example, fact.hs

-- copying cedric's nicely formatted code
fact :: Int -> Int
fact n = if n == 0
    then 1
    else n * fact (n-1)

That's all that really needs to be there. When you want to make real modules, you should do some extra stuff.

Now, open up ghci from the same folder. At the ghci prompt, use the :l command to load the "module"

Prelude> :l fact.hs
[1 of 1] Compiling Main             ( fact.hs, interpreted )
Ok, modules loaded: Main.
*Main> fact 3
6
*Main> fact 10
3628800

I assume it's a very similar process with Hugs. I think hugs requires the file name to be capitalized. ghci simply creates a "Main" module and puts your code in it; that's why the prompt changes from Prelude> to *Main>

When I work on small Haskell functions, I usually keep two terminals open: one for vim and one for ghci. When I change the file in vim (and save it), I just use :r in ghci to reload the new definitions.

*Main> :r
Ok, modules loaded: Main.

Upvotes: 1

user395760
user395760

Reputation:

I assume you type this right into the interactive prompt. Sadly, these are relatively primitive in Haskell - complex definitions, such as fact, can't be entered at the prompt, at least not in the same way you'd normally write them.

You need to put function definitions etc. into modules, then load those via (e.g.) :load fact.hs. There are resources for Hugs specifically that provide more information on this and other topic (I used http://cvs.haskell.org/Hugs/pages/hugsman/index.html to check my assumptions).

Also note that indentation matters, so the code won't work the way you posted it here even when in a module. Those tutorials will have correct versions. If not, they're useless and you should forget them.

Upvotes: 6

Cedric
Cedric

Reputation: 720

The syntax is incorrect. In Haskell, whitespace matters, much like it does in Python. More specifically, if you have text that starts on the first column of a line, the interpreter will think it's a top-level declaration. The correct syntax would be (for example):

fact :: Int -> Int
fact n = if n == 0
  then 1
  else n * fact (n-1)

You could also put the if in one line if you'd like to. So if you're using an interactive prompt you could do:

λ> let fact n = if n == 0 then 1 else n * fact (n-1)

Notice that you'll need to use let in order to define functions on the prompt (at least this is how it's done in GHCi, I'm not sure about Hugs). You'll be better off putting them in a separate file and then loading that in the interpreter. But anyway, a much nicer solution would use pattern-matching in my opinion anyway:

fact :: Int -> Int
fact 0 = 1
fact n = n * fact (n-1)

Here, the interpreter would pattern-match the first argument of the function against the possible cases listed. So if the first argument is null, the result if 1, otherwise apply the function recursively.

Upvotes: 4

Related Questions