TastyCode
TastyCode

Reputation: 5799

Why does my code in Haskell work on command line but not in a file

I have the following code that works well on command line:

ghci> [let square x = x * x in (square 5, square 3, square 2)]
[(25,9,4)]

but when I have it in a file and compile it, it doesn't work and I get an error:

[1 of 1] Compiling Main             ( baby.hs, interpreted )

baby.hs:62:1:
    Parse error: naked expression at top level
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.

Upvotes: 0

Views: 262

Answers (2)

redneb
redneb

Reputation: 23880

A haskell module (i.e source a file), typically contains declarations of the form some_var = expression. This line will evaluate the expression (lazilly), and assign it ("bind" it) to the variable some_var. If you just put an expression by itself (a "naked expression"), the compiler doesn't know what to do with it. So you need to bind it to some variable or do something else with it. So for example, the following will complile:

sumSqaures = [let square x = x * x in (square 5, square 3, square 2)]

Now, this is not a very useful module, and in fact, if you try to compile it as an executable (and not a library), it will fail. This is because executables are supposed to define a variable called main. So if you want a complete program that will compile, you can try this

main = print sumSqaures

sumSqaures = [let square x = x * x in (square 5, square 3, square 2)]

or even just the line

main = print [let square x = x * x in (square 5, square 3, square 2)]

Upvotes: 3

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

The REPL, GHCi, accepts Haskell expressions. Unlike Python, a Haskell module must be composed of declarations.

For example, an expression could be 1+1 but even from a human perspective that makes no sense as a top-level of a source file - there is no variable declared and no operation performed. At the top level you can declare a value, such as:

val = [let square x = x * x in (square 5, square 3, square 2)]

Or in the REPL you can do the same but with let:

let val = [let square x = x * x in (square 5, square 3, square 2)]

Upvotes: 6

Related Questions