为什么我的 Haskell 代码显示“变量不在范围内:main”?

问题描述 投票:0回答:4

当我在 repl.it 网站上的 Haskell 交互式 shell 中输入以下内容时,它运行得很好。

let squareMe x = x * x
let myFruit = ["banana", "apple", "kiwi", "orange"]

但是当我将其输入源文件并单击“运行”时,我收到错误:

<interactive>:3:1: error:
    • Variable not in scope: main
    • Perhaps you meant ‘min’ (imported from Prelude)

我花了几个小时试图理解这个错误并提出解决方案,但距离找到解决方案或理解错误的含义还差得很远。

haskell compiler-errors
4个回答
28
投票

Haskell REPL (GHCi) 和实际的 Haskell 程序有很大不同。

造成这种差异的原因是两种格式的目标。首先,GHCi是一个测试区,而不是一个代码运行区。然而,Haskell 源文件旨在运行某个名为

main
的进程。当您运行源文件时,Haskell 编译器(通常是 GHC)会查找名为
IO
main
操作,并尝试运行它。在这种情况下,没有
main
,所以失败了。

其次,您输入的不是有效的 Haskell 程序,这些声明在 GHCi 中没问题,但在 Haskell 源代码中则不然。这在源文件中是正确的:

squareMe x = x * x

myFruit = ["banana", "apple", "kiwi", "orange"]

注意缺少

let
; Haskell 源文件不使用它来声明事物。

请注意,在 repl.it 上,这仍然会抱怨缺少

main
,但您可以放心地在 REPL 中引用
squareMe
myFruit
。换句话说,错误仍然会出现,但这并不重要,因为您仍然可以使用您在文件中编写的任何内容。

如果您想抑制警告,您可以编写以下行:

main :: IO ()    -- This says that main is an IO action.
main = return () -- This tells main to do nothing.

您可以让程序做很多事情来代替这个。这里有几个例子:

  • main = putStrLn "No errors!"
    运行时会打印
    No errors!
  • main = print myFruit
    运行时会打印
    ["banana", "apple", "kiwi", "orange"]

请注意,这个答案主要适用于 repl.it 站点,尽管一般来说这就是 Haskell 程序的结构。


9
投票

如果您编译 Haskell 源代码,则需要有一个

main
符号作为入口点,就像编译时一样。一个 C 程序。此外,在编译文件中,您必须跳过
let
。例如

squareMe x = x * x

main = putStrLn . show $ squareMe 4

1
投票

如果您正在编写的内容更像是一个库或一组实用例程,而不是一个完整的程序,您可以将其声明为

module
。 然后GHC会把它编译成一个可以链接到其他程序的对象,你也可以在GHCI中加载它。 预计它不会包含
main
例程。

如果将其保存到

.hs
文件:

module Example (squareMe) where

squareMe x = x * x -- Exported to other modules.
myFruit = ["banana", "apple", "kiwi", "orange"] -- Not exported.

使用 GHC 编译此文件将为您提供一个

.hi
文件和一个
.o
文件,并在 GHCI 中运行它将为您提供以下内容:

GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Ok, modules loaded: Example (sx-modulexmpl.o).
Prelude Example> squareMe 2
4

您还可以计算从命令行引用库的表达式。

ghc -e "squareMe 2" Example.hs
打印
4


0
投票

在文本编辑器中打开文件并将其另存为 somecode.hs

somecode.hs:

main = do
  let squareMe x = x * x
  let myFruit = ["banana", "apple", "kiwi", "orange"]

保存并在终端中运行:

runghc somecode.hs
© www.soinside.com 2019 - 2024. All rights reserved.