2013-08-01 5 views
10

私はコマンドラインからint値を取得して、disp関数に渡そうとしています。 GHCによって与えられたHaskell:コマンドライン引数をintとして読み込むには?

import System(getArgs) 

main = do 
    args <- getArgs 
    disp $ read $ head args :: Int 

disp n = take n $ repeat 'S' 

エラーが

Couldn't match expected type `Int' with actual type `[Char]' 
In the expression: disp $ read $ head args :: Int 
In the expression: 
    do { args <- getArgs; 
      disp $ read $ head args :: Int } 
In an equation for `main': 
    main 
     = do { args <- getArgs; 
        disp $ read $ head args :: Int } 

おかげです。

+0

引数をintとして解析するにはread ::(Read a)=> [Char] - > aを使用する必要があります(Intは読み込みのインスタンスです) – bennofs

+0

上記の 'read'を使用しています。 prelude作品から 'read'を使う例: 'take(read $ head [" 5 "、" 4 "、" 3 "] :: Int)[x | x < - [1..19]] 'は[1,2,3,4,5]を与えます。 – boring

+1

あなたがそこに追加した ':: Int'を削除するだけです。それは、使用する 'read'を使い果たします。 –

答えて

12

問題は優先度があります。タイプシグネチャは常に式全体に適用しようとします(括弧を使用してスコープのみ)。したがって、disp $ read $ head args :: Int(disp $ read $ head args) :: Intと解釈されますが、これは明らかに正しくありません。あなたはそうのように括弧を使用することができ、次のいずれか

disp (read $ head args :: Int) 

またはGHCは、この場合には、それを推測することができますよう、型シグネチャを省略:

disp $ read $ head args 

このコードはまだあなたので、そのままでは動作しませんあなたはIOアクションを生成する必要があるので、IOモナドにあります。次の例のように、結果を印刷することでこれを行うことができます。

putStrLn $ disp $ read $ head args 
+0

はい、動作します! ">あなたはIOモナドにいるので、IOアクションを生成する必要があります。" IOモナドの中に入力していますが、IO型ではない戻り値に対してIO出力を生成することは必須ですか?ここのハスケル・ノブ。さて、私はIOについてもっと読むべきですが、これについての考えも役に立ちます。 – boring

+2

@kadaj IO-doブロック内のすべてのステートメントはIOアクションを返す必要があります。ただし、let: 'let myDispResult = disp $ read $ head args'を使用して、任意の型の変数を割り当てることができます。 – bennofs

+2

出力を生成する必要はありませんが、IOアクションを作成する必要があります。計算された値を返す場合は、IOモナドの値をラップする 'return'を使うことができます。つまり、 'main'の型は' IO String'ではなく 'IO()'でなければならないので、この場合は動作しません。 – sepp2k

5

あなたがそこに追加した明示的なタイプを削除すれば正常に機能します。型推論を信じてください。 :)新しいエラーを修正するために、print $ ...、またはそれに類するものを追加してください。

何が起こるかは、takeのタイプが分かっているので、dispが期待する引数のタイプもわかっています。それはIntです。したがって、適切なreadが適用されます。

以下を実行してください。

+2

しかし、 'disp'は' String'を生成するので、おそらく 'putStrLn'を追加したいでしょう。 – kosmikus

+1

@kosmikusまたは印刷します。それは尋ねられたもの以外にもあります。 –

+0

はい 'print'も同様です。 – boring

10

あなたがそうのような整数のコマンドライン引数を引っ張ってカプセル化することができます

getIntArg :: IO Int 
getIntArg = fmap (read . head) getArgs 

モナドはファンクタであるため、働きます。あるいは、liftMで同じことをすることもできます。

あなたmain機能がちょうどとなりその方法:他の回答で述べたように、あなたがdispに印刷機能のいくつかのタイプを追加提供

main = do 
    n <- getIntArg 
    disp n 

関連する問題