import Data.List import System.Directory import System.Posix.Files as PF import Text.Printf data StMode = BlkDev | CharDev | Dir | NamedPipe | RegFile | Sock | SymLink deriving (Eq, Ord) instance Show StMode where show BlkDev = "block device" show CharDev = "character device" show Dir = "directory" show NamedPipe = "named pipe" show RegFile = "regular file" show Sock = "socket" show SymLink = "symbolic link" getStMode :: FilePath -> IO StMode getStMode fp = getFileStatus fp >>= (\x -> case () of _ | isBlockDevice x -> return BlkDev | isCharacterDevice x -> return CharDev | isNamedPipe x -> return NamedPipe | isRegularFile x -> return RegFile | isDirectory x -> return Dir | PF.isSymbolicLink x -> return SymLink | isSocket x -> return Sock) groupByStMode :: [FilePath] -> IO [[(FilePath, StMode)]] groupByStMode fps = do stModes <- mapM getStMode fps let zipped = zip fps stModes sorted = sortBy (\(_, m0) (_, m1) -> compare m0 m1) zipped grouped = groupBy (\(_, m0) (_, m1) -> m0 == m1) sorted return grouped ls :: FilePath -> IO [FilePath] ls fp = listDirectory fp >>= (\list -> return $ map ((fp ++ "/") ++) list) main = ls "/proc/" >>= groupByStMode >>= mapM_ (\list -> let (toShow, toHide) = splitAt 10 list in printf "%-30s%s\n" "path" "type" >> mapM_ (\x -> printf "%-30s%s\n" (fst x) (show $ snd x)) toShow >> printf "%-30s%s" (show $ length toHide) "omited\n\n")