2012-05-16 60 views
0

我想要一個目錄中文件的排序列表。如何將sort函數應用於包含IO monad的列表?從目錄中獲取已排序的文件列表

import System.Directory 
import Data.List 

sortedFiles :: FilePath -> IO [FilePath] 
sortedFiles path = do 
    files <- getDirectoryContents "." 
    return sort files     -- this does not work 

回答

8

原來的問題就是缺少括號的,因爲目前return被應用到兩個參數(sortfiles),只是修復了:

sortedFiles path = do 
    files <- getDirectoryContents "." 
    return (sort files) 

如果你願意,你可以在fmap排序功能目錄內容。它種有一個很好的,直接的感覺,基本上解除了排序功能成的IO單子:

sortedFiles path = sort `fmap` getDirectoryContents path 
+0

感謝FMAP例子!我認爲fmap適用於每一個列表項目,但我也可以fmap整個'[FilePath]'。 – Jakob

+0

的確,這裏'fmap'來自'IO'實例,而不是'[]'(list)實例。 – ScottWest

4

return函數不帶兩個參數。 (這是一個例外,但對初學者來說並不重要 - 它不會像你期望的那樣做。)這是因爲return是一個函數,而不是語法。函數的所有標準語法規則都適用於它。你想通過返回sort files的結果,但這並不是你使用的語法所說的。您需要return (sort files)return $ sort files

這兩者完全相同。後者稍微更習慣Haskell。大多數人更喜歡使用$運算符來使用括號,當兩者都具有相同的可讀性時。

3

其他已經指出,缺乏括號中。

但這裏有一個更短,更可讀的版本:

import System.Directory 
import Data.List 
import Control.Applicative 

sortedFiles :: FilePath -> IO [FilePath] 
sortedFiles = sort <$> getDirectoryContents 
+0

您能否簡要說明「<$>」是如何定義的? – Jakob

+0

它在'Control.Applicative'中定義,它是'fmap'的同義詞。 – Vitus

相關問題