为什么 ghci 的行为与 runHaskell 不同?

Why does ghci behave differently to runHaskell?

我的目标是将 ghci 的一些步骤从 bash 脚本传送到 运行,然后干净地退出。网上的评论says为此使用runhaskell

这是 command 我正在尝试 运行:

ghci> import System.Random 

ghci> random (mkStdGen 100) :: (Int, StdGen) 

预期结果类似于:

(-3633736515773289454,693699796 2103410263)

当我将其放入文件 randomtest.hs 并使用 runhaskell 执行它时,出现以下错误:

randomtest.hs:3:1: error:
    Invalid type signature: random (mkStdGen 100) :: ...
    Should be of form <variable> :: <type>

我需要提示才能朝着正确的方向前进。

我的问题是:为什么 ghci 的行为与 运行Haskell 不同?

ghci 是一个 REPL(读取、评估、打印循环)。但是,runhaskell 几乎与将程序编译成可执行文件,然后 运行ning 它几乎相同。 GHCI 允许我们 运行 单独的函数和任意表达式,而 运行haskell 只是调用主函数并解释文件,而不是编译它,然后 运行 编译它。

正如@AJFarmar 指出的那样,GHCI 最适合用于调试和测试您正在构建的程序,而 运行haskell 是 运行 整个程序而无需编译的好方法.

所以,要解决你的问题,我们只需要给程序一个主函数。 ghci 对输入解释器且未绑定到变量的每个表达式的结果调用 print

所以,我们的主要功能可以是:

main = print (random (mkStdGen 100) :: (Int, StdGen))

我们还需要导入System.Random,所以整个文件变成:

import System.Random

main = print (random (mkStdGen 100) :: (Int, StdGen))

那么,我们可以运行如预期的那样:

[~]λ runhaskell randomtest.hs 
(-3633736515773289454,693699796 2103410263)

如果我们想从 运行haskell 中执行多个命令,我们可以在 main 中的 do 块中添加更多命令:

import System.Random

main = do
    print (random (mkStdGen 100) :: (Int, StdGen))
    let x = 5 * 5
    print x
    putStrLn "Hello world!"