2009-11-04 12 views
31

テキストのインデックスを作成するためにHaskellでコードをまとめました。 - > IO文字列タイプのハスケル関数:IO String-> String

index readFile "input.txt" 

readFileのは、タイプのFilePathであるため動作しません。今、私はこの機能をファイルから読み込んだ文字列を与えたい

index :: String -> [(String, [Integer])] 
index a = [...] 

:トップ関数は次のようになります。

「IO文字列」推論されたタイプに対して予想される型「文字列」 と一致しませんでした

私はエラーが表示されますが、私は型を持つ任意の関数を見つけることができません。

IO String -> String 

私は、成功への鍵はいくつかのモナドの下にあると思いますが、私は自分の問題を解決する方法を見つけることができませんでした。

+3

は良いモナドのチュートリアルについてはこちらをご覧ください08/you-could-have-invented-monads-and.html –

+1

他の良いリソースはここにあります。関連するセクションを見て、画面の右下に表示してください。 –

答えて

37

readFileアクションを呼び出す関数を簡単に書くだけで、その結果をインデックス関数に渡すことができます。

readAndIndex fileName = do 
    text <- readFile fileName 
    return $ index text 

しかし、IOモナドは、それを使用するすべてのものは汚染ので、この機能はタイプがあります。

readAndIndex :: FilePath -> IO [(String, [Integer])] 
+3

それは小さな文章です: "IOモナドはそれを使用するすべてのものを汚しています"。私はこれが当てはまると仮定しましたが、それが今確認されているのはうれしいです。ありがとう^^ – drumfire

15

IOモナドの一部を取り除くことはできませんIO Stringです。つまり、関数をIO [(String, [Integer])]に戻す必要があります。

私はモナドについての詳細を学ぶお勧めしますが、今のところ、あなたはliftM機能を離れて得ることができます:それは非モナド関数を受け取り

liftM :: Monad m => (a -> b) -> m a -> m b 

と:

liftM index (readFile "input.txt") 

liftMこの署名を持っていますモナド関数に変換します。

27

はそのような機能はありませんなぜ非常に良い理由がありますが。

ハスケルは機能的純度という概念を持っています。これは、同じパラメータで呼び出されたときに関数が常に同じ結果を返すことを意味します。 IOが許可されている場所は、IOモナド内にあります。

機能

index :: IO String -> String 

が*された場合、私たちは突然、IOアクションどこでも例えば、呼び出すことによって行うことができます:

index (launchMissiles >> deleteRoot >> return "PWNd!") 

機能純度は非常に便利な機能我々ドンでありますコンパイラが関数をより自由に並べ替えることができるので、意味を変えずに別のコアに呼び出すことができ、プログラマーにセキュリティの感覚を与えることができるので、k今は関数がその型からできることとできないこととは何か。

※実際には、は、です。それはunsafePerformIOと呼ばれ、それはのために非常に、非常に良い理由と呼ばれています。 あなたがしていることを100%確信していない限り、使用しないでください! http://blog.sigfpe.com/2006/:

あなたがモナドに見てみたいことがあります
+13

私は "あなたがしていることを200%確信していない限り、それを使わないでください"と言ったり、もっと単純で "しないでください"と言っています。 –

+6

私はunsafePerformIOの最良の使用法は、常に同じことを返すべきであるプロセスにシェルすることです。すなわち、標準ライブラリによってネイティブにサポートされていないシステム計算。 – alternative

+4

SOをブラウズ中に見つけたばかりの私の古いコメントに追加:FFIにも役立ちます – alternative

8
fmap index $ readFile "input.txt" 

または

readFile "input.txt" >>= return . index 

とファンクタ