2011-08-15 6 views
3
checkstring :: [String] -> Int -> [String] 
checkstring p n = do z <- doesFileExist (p !! n) 
    if z 
    then p 
    else error $ "'" ++ (p !! n) ++ "' file path does not exist" 

"n"を調べると、文字列の要素がチェックされます(n = 2の場合、リストの2番目の文字列があるかどうかを確認します)。存在していれば、元の文字列リストを返します。そうでなければ、エラーになります。なぜこれをしますか? :Haskellで奇妙な結果が返ってくる

Couldn't match expected type `[t0]' with actual type `IO Bool' 
    In the return type of a call of `doesFileExist' 
    In a stmt of a 'do' expression: z <- doesFileExist (p !! n) 
+0

http://stackoverflow.com/questions/6904169/managing-the-io-monadの回答とディスカッションを参照 – MatrixFrog

答えて

6

doesFileExistのタイプはString -> IO Boolです。あなたのプログラムがファイルが存在するかどうかを知りたければ、ファイルシステムと対話する必要があります。これはIOアクションです。もしあなたのcheckString関数がそれを行うようにしたいのであれば、ある種のIOベースのタイプを持つ必要もあります。例えば、私はそれを試していないが、このような何かが仕事だと思う:

checkstring :: [String] -> Int -> IO [String] 
checkstring p n = do z <- doesFileExist (p !! n) 
    if z 
    then return p 
    else error $ "'" ++ (p !! n) ++ "' file path does not exist" 
+0

IOベースのタイプに変更するにはどうすればよいですか? – ArchHaskeller

+0

には例が含まれています – MatrixFrog

0

私はこの問題は、あなたのタイプの署名が、それはいくつかの他のモナドであると仮定することdoブロックを強制することだと思います。たとえば、リストのモナドで作業しているとします。その後、あなたはリストモナドの場合

myFcn :: [String] -> Int -> [String] 
myFcn p n = do 
    return (p !! n) 

を書くことができ、returnは単にシングルトンのリストを返しますので、あなたは、のような動作を取得

> myFcn ["a", "bc", "d"] 1 
["bc"] 

(私の個人的な意見は、それが可能だろうということですGHCにタイプミスを引き起こす可能性がある一般的な間違いを印刷するオプションがある場合は非常に役に立ちます;私は理解する時間がかかるタイプのエラーメッセージがたくさんあるという点で、質問者に同情します。

2

彼の答えでMatrixFrogが何を言及しているかを追加してください。あなたの関数のシグネチャ、すなわち[String] -> Int -> [String]を見ると、この関数は純粋な関数であり、関数本体の中での記号がString -> IO Boolであり、IOの存在がそれを示しているは不純な機能です。つまり、IOが含まれています。 haskellには、不純な機能と純粋な機能との間に厳密な分離があります。実際には、機能が不純な機能以外の機能を呼び出している場合は、問題はありません。だからあなたのケースでは、あなたの関数checkStringは不純である必要があり、それは返すようにすることができますIO [String]、これはMatrixFrogが彼の答えで述べたものです。それだけで行うには、リストから特定の文字列を必要としてあなたの関数は、文字列のリスト全体を必要としないよう、
checkString :: String -> IO (Maybe String)

別のノートで

、私はあなたがのようなものにするための関数を作ることができることを示唆していますその作業とエラーを投げるのではなく、おそらくエラーを検出するために使用することができます。 これは単なる提案にすぎませんが、機能の使用方法によっても異なります。