2

いくつかのコマンド ライン引数を取るプログラムがあります。

最初のコマンド ライン引数が整数のカンマ区切り値 (CSV) リストであるとします。

"1,2,4,8,16"最初の引数をに変換したい[1,2,4,8,16]。文字列をリストに解析しようとしましたIntが、コンパイル エラーが発生しました。

Haskell コード:

import System.Environment
import Data.List
import Text.Regex

main = do
  args <- getArgs

  ints <- if   (length args > 1)
          then (mapM read (splitRegex (mkRegex ",") (args!!1)))
          else [1,3,5] -- defaults
  print (ints)

コンパイル エラー:

myProg.hs:10:16:
    Couldn't match expected type `IO' with actual type `[]'
    In the expression: [1, 3, 5]
    In a stmt of a 'do' block:
      ints <- if (length args > 1) then
                  (mapM read (splitRegex (mkRegex ",") (args !! 1)))
              else
                  [1, 3, 5]
    In the expression:
      do { args <- getArgs;
           ints <- if (length args > 1) then
                       (mapM read (splitRegex (mkRegex ",") (args !! 1)))
                   else
                       [1, ....];
           print (ints) }

このタイプのエラーが何を意味するのかわかりません。誰かが型エラーを説明し、コードを変更して目的の結果を達成する方法を教えていただければ幸いです。

4

2 に答える 2

3

そこでIOアクションを実行していないため<-、定義するために使用したくありません。バインディングintsを使用するだけです。これにより、 への呼び出しをプレーンなletに置き換えることもできます。mapMmap

最初の適切な引数も、C で見られるような 1 ではなく、0 でインデックス付けされます。 を使用headして、それを取得することもできます。

let ints = if   length args >= 1
           then map read (splitRegex (mkRegex ",") (head args))
           else [1, 3, 5]
于 2013-11-09T20:18:22.877 に答える
2

表現

if   (length args > 1)
then (mapM read (splitRegex (mkRegex ",") (args!!1)))
else [1,3,5] -- defaults

2 つのケース (then、else) の値が一致しないため、型が正しくありません。mapM の型は

mapM :: Monad m => (a -> m b) -> [a] -> m [b]

したがって、then ブランチは、いくつかのモナド m (この場合は IO) のタイプ m [b] です。ただし、else ブランチは単なる数字のリストです。書くことでエラーを修正できます

return [1,3,5]

else の場合、そのタイプは IO [Int] になります。

しかし、これはおそらく最善の方法ではありません。then ブランチに問題があります。関数 read は IO に値を返さないため、ここでは mapM の最初の引数として適切ではありません。実際、ints の値は引数 (args) の純粋な関数として取得されるため、IO でこの計算を行う理由はありません。タイプの関数として、メインの外で実装することをお勧めします

extractInts :: [String] -> [Int]

次に、次のようにメインに組み込むことができます。

main = do
  args <- getArgs
  let ints = extractInts args
  print ints
于 2013-11-09T20:31:01.587 に答える