、いくつかのスタックオーバーフローの質問への回答でドン・スチュワートによって書かれたコードを取る:ハスケル:なぜメインメソッドのGHCによって推論された型は完全ではありませんか?例えば
import Control.Monad
import qualified Data.HashTable as H
import System.Environment
main = do
[size] <- fmap (fmap read) getArgs
m <- H.new (==) H.hashInt
forM_ [1..size] $ \n -> H.insert m n n
v <- H.lookup m 100
print v
はGHCiの中でそれをロードします。
:t getArgs ---> getArgs :: IO [String]
:t main ---> main :: IO()
は、なぜメインの型シグネチャはgetArgs :: IO [String]
が呼び出されているという事実を反映していませんか?
バイナリを実行するときに引数を付けることができます。 <prog> 145
が返されますJust 100
しかし、GHCiでは、次のことはできません。main 145
がエラーになります。どのようにGHCiでこのプログラムを実行し、議論をしますか?
ありがとうございました。私は* do *が>> =の構文的砂糖であり、その署名が*(>> =)::(Monad m)=> m a - >(a - > m b) - > m b *であることを理解する。しかし、モナド演算を使用する場合でも、型シグネチャが* getArgs :: IO [String] *であるgetArgsが計算で使用されているという事実をコンパイラが利用できないのでしょうか?より意味のあるタイプシグネチャを提供しますか?あるいは、これはまったく不可能なのでしょうか? –
ハスケルではありません。既にそこにあるもの(IO)を超えて、そうすることにどのような価値があるのかは分かりません。これは、コンパイラにとって有益な情報ですが、それ以外の情報はありません。あなたが本当に考えていることが、「IO」を分割していない限り、それは物流上の悪夢となる多年にわたる議論の話題です。 – geekosaur
これはあなたのコードを 'mainX :: [String] - > IO()'関数に入れて、 'main = getArgs >> = mainX' –