-3

I need the list for further operations on strings. I do not want just print the list of strings!

my code so far

https://gist.github.com/bigos/0067a62e15dbed264ce6ef92e0eca58c

clarification of my goal

I would consider the question answered if somebody provided an example where code traverses through the list of filenames and prints the first half of each filename.

explanation why I could not do it

This question How to get normal value from IO action in Haskell has the answer submitted by Riccardo T.

has nice pseudocode example.

ruby_object
  • 1,229
  • 1
  • 12
  • 30

2 Answers2

6

You can use (=<<) :: ([String] -> IO b) -> (IO [String] -> IO b) to teach a function which expects lists of strings how to handle a value like listDirectory "." that produces IO-wrapped lists of strings instead. In idiomatic Haskell, its flipped form, (>>=) :: IO [String] -> ([String] -> IO b) -> IO b, is more common, because its arguments appear in the order that IO is executed. So, for example:

import System.Directory

printFirstHalfOfSingleString :: String -> IO ()
printFirstHalfOfSingleString s = putStrLn (take (length s `div` 2) s)

printFirstHalfOfEachString :: [String] -> IO ()
printFirstHalfOfEachString = mapM_ printFirstHalfOfSingleString

main = listDirectory "." >>= printFirstHalfOfEachString
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • My mistake was trying to pass the second argument to mapM_ like this: mapM_ printFirstHalfOfSingleString (listDirectory ".") – ruby_object Aug 26 '18 at 13:16
  • 2
    @ruby_object Why not just say that in your question? If you'd posted that code, you'd've probably gotten an answer much quicker. – melpomene Aug 26 '18 at 13:26
  • In Haskell part of the problem is knowing what question to ask. After failure after failure and not knowing how to read the error messages I just fell back to a standard imperative question I would ask in that situation. – ruby_object Aug 26 '18 at 13:31
  • my version using =<< operator. mapM_ (\l -> putStrLn l) =<< listDirectory "." – ruby_object Aug 26 '18 at 13:32
1

Are you asking for getDirectoryContents, the equivalent of ls in shell ?

Here is a program that lists the file names below the current working directory, printing half of each :

import System.Directory

firstHalf :: String -> String
firstHalf s = take (length s `div` 2) s

main = do
    -- Get the current working directory
    current <- getCurrentDirectory
    -- Lists the file in current
    children <- getDirectoryContents current
    mapM putStrLn (map firstHalf children)

In your gist code, try listDirectory = getDirectoryContents and take care, getDirectoryContents result also contains "." and ".."

Suricat
  • 131
  • 4
  • trying to write own ls would be a step towards achieving what I want. I guess part of the problem is that I do not understand how function arguments work in Haskell. – ruby_object Aug 26 '18 at 17:44