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)
私はこのエラーを理解しようとして数時間前から解決策を考え出していましたが、解決策を見つけることやエラーの意味を理解することには近づきませんでした。
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プログラムの構造です。
Haskellソースをコンパイルする場合は、コンパイル時と同様に、エントリポイントとしてmain
記号が必要です。 Cプログラム。また、コンパイルされたファイルでは、let
sをスキップする必要があります。例えば。
squareMe x = x * x
main = do
putStrLn (show (squareMe 4))
作成しているものが、完全なプログラムというよりもライブラリまたはユーティリティルーチンのセットに近い場合は、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
を出力します。