Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a function in Haskell - beginner problem

Tags:

haskell

Just started learning Haskell.

I have an empty source file with this inside:

pe :: (Integral a) => a -> a
pe y = sum [x | x <- [1..y-1], x `mod` 3 == 0 || x `mod` 5 == 0]

Now if I ghci this, I can call pe like so:

*Main> pe 1000
233168

How do I call it from within my source file? If I have

pe 1000

it returns a cryptic error:

GHC stage restriction: `pe'
   is used in a top-level splice or annotation,
   and must be imported, not defined locally
 In the expression: pe 1000

Do I need to declare it in main or something?

like image 376
Dominic Bou-Samra Avatar asked May 28 '11 00:05

Dominic Bou-Samra


2 Answers

Yes, you need to hook it up to your main function. For example,

main = print (pe 1000)

If you want to have multiple calls, you can combine them with do-notation:

main = do
    print (pe 500)
    print (pe 1000)
like image 162
hammar Avatar answered Oct 03 '22 13:10

hammar


A Haskell source file contains a sequence of definitions, not expressions. So you can't just put an expression in the top level of the file, you have to put it inside the body of a definition. So since pe 1000 is not a definition, you get an error.

But why such a cryptic error message? GHC has an extension called Template Haskell, which allows you to programmatically create definitions at compile time. To achieve this it allows you to put an expression in a place where usually only definitions are allowed and evaluates the expression at compile time and replace the expression with its result (which must be a definition) - this is called splicing and the expression is then called a splice. Such a splice needs to meet two requirements:

  1. Any identifiers used in the expression must be defined in a different source file (this is required so that the used functions are already compiled when the expression is encountered and thus can be called during compile-time)
  2. The type of the expression must be a Template Haskell type which represents a valid definition.

So since your expression pe 1000 appears somewhere where only definitions are allowed, GHC assumes it is a splice. However since it does not meet the first of the above criteria, i.e. it is defined in the current file instead of a different file, GHC complains about that. Of course it doesn't meet the second condition either, but GHC hasn't gotten to that yet, when it produces the error message. If pe were defined in a different source file, you'd have gotten an error message complaining about the fact that pe has the wrong type.

like image 36
sepp2k Avatar answered Oct 03 '22 13:10

sepp2k