为什么我在 Haskell 中的代码在命令行上有效,但在文件中无效

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

我有以下在命令行上运行良好的代码:

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

但是当我把它放在一个文件中并编译它时,它不起作用并且我得到一个错误:

[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.

REPL GHCi 接受 Haskell 表达式。与 Python 不同,Haskell 模块必须由声明组成。

例如,表达式可以是 1+1,但即使从人类的角度来看,它作为源文件的顶层也毫无意义 - 没有声明变量,也没有执行任何操作。在顶层你可以声明一个值,比如:

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

或者在 REPL 中你可以做同样的事情,但是 let:

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

A haskell 模块(即源文件),通常包含 some_var = expression 形式的声明。这一行将计算表达式(惰性),并将它("bind" 它)分配给变量 some_var。如果你只是单独放置一个表达式 (a "naked expression"),编译器不知道如何处理它。所以你需要将它绑定到某个变量或用它做其他事情。因此,例如,以下将编译:

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

现在,这不是一个非常有用的模块,事实上,如果您尝试将其编译为可执行文件(而不是库),它将失败。这是因为可执行文件应该定义一个名为 main 的变量。所以如果你想要一个可以编译的完整程序,你可以试试这个

main = print sumSqaures

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

甚至只是行

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