2016-04-28 15 views
8

Wie filtert man IO [Maybe String], um nur die Just Werte der Liste unter Verwendung zu behalten und den IO Kontext zu behalten.Filter IO [Maybe String] zu IO [String]

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

Meine aktuelle Lösung ohne den bind-Operator:

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

ich lerne derzeit Haskell und versuchen zu verstehen, wie die verschiedenen Funktionen der Standardbibliothek zu verwenden. Meine Lösung funktioniert, aber ich denke, es gibt einen saubereren Weg.

+5

Und nur zum Spaß, können Sie es wirklich nennen mit dem Apostroph "binDoesnistExist", und es wird immer noch funktionieren. –

Antwort

9

würde eine kurze Lösung

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

Sie brauchen nicht die >>= Betreiber, dass für.

Hinweis: (\x -> binDoesntExist x) = binDoesntExist

3

Aus dem Kommentar, den Sie auf binDoesntExist geschrieben haben, vermute ich, dass Sie eher eine andere Art Unterschrift haben könnten, nämlich:

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

Die Umsetzung dieser Signatur wird wahrscheinlich einfacher als Ihre bestehende Implementierung; und zusätzlich Ihre missingBin wird ziemlich viel einfacher als gut:

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

Diese Diskussion geht davon aus, dass Ihre vorhandene Funktion liefert immer genau die String es übergeben wird (wenn es gibt jeden String überhaupt); aber diese Annahme scheint mir nicht so weit zu sein.

+0

Sie haben recht damit, 'missingBin' in' IO Bool' zu verwandeln. Der schwierige Teil nach Verstehen-wie-Haskell-Arbeiten besteht darin, Haskell zu lernen. Danke für den Tipp. – Paradiesstaub