web-dev-qa-db-ja.com

Haskellコードが「変数がスコープ内にありません:メイン」と言っているのはなぜですか?

repl.it WebサイトのHaskellの対話型シェルで次のように入力すると、完全に機能します。

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)

私はこのエラーを理解しようとして数時間前から解決策を考え出していましたが、解決策を見つけることやエラーの意味を理解することには近づきませんでした。

10
branty1970

Haskell REPL(GHCi)と実際のHaskellプログラムはかなり異なります。

この違いの理由は、2つの形式の目標です。まず、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プログラムの構造です。

15
AJFarmar

Haskellソースをコンパイルする場合は、コンパイル時と同様に、エントリポイントとしてmain記号が必要です。 Cプログラム。また、コンパイルされたファイルでは、letsをスキップする必要があります。例えば。

squareMe x = x * x

main = do
    putStrLn (show (squareMe 4))
4
mschmidt

作成しているものが、完全なプログラムというよりもライブラリまたはユーティリティルーチンのセットに近い場合は、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.hs4を出力します。

0
Davislor