モジュール内 System.Info
これらの関数が表示されます。
os :: String
Arch :: String
compilerName :: String
compilerVersion :: Version
なぜIO
がないのですか?彼らはシステムにアクセスしています...私は間違っていますか?私の期待は次のようなものでした:
os :: IO String
Arch :: IO String
compilerName :: IO String
compilerVersion :: IO Version
使用事例:
print os -- "darwin"
print Arch -- "x86_64"
print compilerName -- "ghc"
runtimeでその情報を取得していません。これらは、システムにインストールされているとおりにコンパイラーでハードコーディングされます。
compilerName :: String
compilerName = "ghc"
os
のようなものでも
os :: String
os = Host_OS
それ以外は未定義の名前で定義されているHost_OS
(大文字で始まる値??)これは、インストール中に置き換えられる単なるプレースホルダーであることを示唆しています。
誰かが私を訂正することもできます(お願い!)が、{-# LANGUAGE CPP #-}
そのファイルの先頭にあるプラグマは、Host_OS
などは、コンパイル前にCプリプロセッサによって適切な文字列に置き換えられます。
質問は良いものです。そのような答えは、それらの値はプログラムのコンパイルごとに静的であるということです。これらは基本的にプログラムにコンパイルされ、その後変更されることはありません。そのため、それらを定数として処理しても、(GHCが使用する仮定では)何も壊れません。また、IOアクションよりも単純な定数を使用する方が便利です。
しかし、それはあらゆる種類の従来の推論です。 Haskellは古い言語です。 (実際には、それはJavaより数年前のものです。)多くのライブラリは、もはやベストプラクティスとは見なされない理由で構築されています。これらはその例です。それらを公開する最新のライブラリは、コンパイル後に結果が変化しない場合でも、おそらくそれらをIOアクションにします。ソースレベルで定数ではないものをIOアクションの後ろに置くと、さらに便利です。ただし、32ビットプラットフォームと64ビットプラットフォーム間でInt
のサイズを変更するなど、いくつかの注目すべき例外があります。
いずれにせよ...あなたの期待は確かであり、それらのタイプは歴史的な奇妙さの結果です。