Home > Mobile >  How to find line count of file in Haskell? (how to remove for loop?)
How to find line count of file in Haskell? (how to remove for loop?)

Time:11-16

Aspiring haskeller here. I wrote a script to take a filepath argument, read the contents where each line will be a relative filepath, and count the lines of each filepath and print it to the command line. It relies on System.Directory.Internal.Prelude.for_ to loop through the file's contents and print each length to the console.

  • Question 1: How would you remove the for loop?
  • Question 2: If getFileLength had a signature of `FilePath -> IO(Maybe(Int)), how would you refactor the program? (Does this question make sense?)
import System.Environment
import System.Directory
import System.IO
import Data.Char
import System.Directory.Internal.Prelude (for_)

main = do
  (configPath:_) <- getArgs
  configContents <- readFile configPath 
  let filePaths = lines configContents
  for_ filePaths (\path -> do getFileLength path)

getFileLength :: FilePath -> IO()
getFileLength path = do
  contents <- readFile path
  putStrLn $ "- [ ] "    path    " ("    show (length (lines contents))    ")"

Thank you

CodePudding user response:

You can use mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m () or traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ():

main :: IO ()
main = do
  (configPath:_) <- getArgs
  configContents <- readFile configPath
  mapM_ getFileLength (lines configContents)

or:

import Data.Foldable(traverse_)

main :: IO ()
main = do
  (configPath:_) <- getArgs
  configContents <- readFile configPath 
  traverse_ getFileLength (lines configContents)
  • Related