Search code examples
haskellghc

How to prnt a directory contents in Haskell


I'm using getDirectoryContents along toText derivative with fldmap.

The error that occur is:

IoString.hs:17:5: error:
    • Couldn't match expected type: FilePath -> IO ()
                  with actual type: IO b0
    • In a stmt of a 'do' block:
        contents <- getDirectoryContents "/home/lukas"
      In the expression:
        do contents <- getDirectoryContents "/home/lukas"
           contents >>= map print toText
      In an equation for ‘main’:
          main
            = do contents <- getDirectoryContents "/home/lukas"
                 contents >>= map print toText
   |
17 |     contents <- getDirectoryContents "/home/lukas"
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

and more others below.

In annex the code:


--{-# LANGUAGE OverloadedStrings #-}

module Main where
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Text (pack, Text)
import System.Directory (getDirectoryContents, getCurrentDirectory, makeAbsolute)
import GHC.Real (reduce)

parse xs = foldMap pack

toText :: [FilePath] -> Text
toText = foldMap pack

main :: FilePath -> IO ()
main = do
    contents <- getDirectoryContents "/home/lukas"
    contents >>= map print toText 

Try to read the directory contents, expect to print.


Solution

  • A basic imperative-like for loop:

    import Data.Foldable (for_)
    
    main :: IO ()
    main = do
        contents <- getDirectoryContents "/home/lukas"
        for_ contents $ \f -> do -- "do" not really needed if the body is one line
            print f
    

    This can be shortened in many ways, e.g.

    import Data.Foldable (traverse_)
    
    main :: IO ()
    main = do
        contents <- getDirectoryContents "/home/lukas"
        traverse_ print contents
    
    -- or
    
    main :: IO ()
    main =
        getDirectoryContents "/home/lukas" >>= traverse_ print
    

    traverse_ and for_ are the same function, but with their arguments flipped.