2016-04-28 12 views
8

IO [Maybe String]をフィルタリングする方法は、を使用してリストのJustの値を保持し、IOコンテキストを保持するだけです。バインド・オペレータなしフィルタIO [多分文字列]からIO [文字列]

-- returns Just, if the passed binary-name is not present on the system 
binDoesntExist :: String -> IO (Maybe String) 
binDoesntExist ... 

私の現在のソリューション:

missingBin :: [String] -> IO [String] 
missingBin xs = do 
    ys <- mapM (\x -> binDoesntExist x) xs 
    return $ catMaybes ys 

私は現在、Haskellのを学習し、標準ライブラリの異なる機能を使用する方法を理解しようとしています。私のソリューションはうまくいきますが、もっとクリーンな方法があると思います。

+5

ちょうど楽しみのために、あなたは実際にそれをアポストロフィで 'binDoesn'tExist'という名前にすることができます。それでも動作します。 –

答えて

9

短いソリューションは、あなたがそのための>>=オペレータを必要としない

missingBin :: [String] -> IO [String] 
missingBin = fmap catMaybes . mapM binDoesntExist 

だろう。

注:binDoesntExistに書いたコメントから(\x -> binDoesntExist x) = binDoesntExist

3

が、私はつまり、あなたはかなり異なるタイプの署名を持っているかもしれないと思われる:

-- returns True if the passed binary is not present on the system 
binDoesntExist :: String -> IO Bool 
binDoesntExist = ... 

この署名の実装は、おそらくになります既存の実装よりも簡単です。そしてはさらにあなたmissingBinが同様にかなり単純になります:

missingBin :: [String] -> IO [String] 
missingBin = filterM binDoesntExist 

をこの議論は、既存の関数は常に(それがすべてで任意のStringを返した場合)、それが渡された正確Stringを返すことを想定しています。この仮定は私にはそれほど遠くはないように見えます。

+0

'missingBin'を' IO Bool'に変更するのは正しいです。ハスケルを理解する方法の後の難しい部分は、ハスケルの考え方を学ぶことです。先端に感謝します。 – Paradiesstaub