Haskell interact function

后端 未结 2 1378
隐瞒了意图╮
隐瞒了意图╮ 2020-12-14 17:18

I’m new to Haskell and have a problem with interact function. This is my sample program:

main :: IO ()
main = interact inputLength

inputLength          


        
相关标签:
2条回答
  • 2020-12-14 17:35

    The String -> String argument given to interact should take a string containing all the input and return a string containing all the output. The reason you see output after pressing enter with interact (map toUpper) is because map toUpper acts lazily -- it can start giving output before all the input is known. Finding the length of a string is not like this -- the whole string must be known before any output can be produced.

    You need to either signal an EOF to say that you are done entering input (in the console, this is Control-D on Unix/Mac systems, I believe it's Control-Z on Windows), then it will give you the length. Or you can find the length of each line by saying so:

    interact (unlines . map inputLength . lines)
    

    This will always be lazy in each line, so you know you can get one output after each input.

    Since acting on lines is such a common pattern, I like to define a little helper function:

    eachLine :: (String -> String) -> (String -> String)
    eachLine f = unlines . map f . lines
    

    Then you can do:

    main = interact (eachLine inputLength)
    
    0 讨论(0)
  • 2020-12-14 17:52

    A more reusable solution:

    main = interactLineByLine processLine
    
    -- this wrapper does the boring thing of mapping, unlining etc.... you have to do all the times for user interaction
    interactLineByLine:: (String -> String) -> IO ()
    interactLineByLine f = interact (unlines . (map processLine) . lines) 
    
    -- this function does the actual work line by line, i.e. what is
    -- really desired most of the times
    processLine:: String -> String
    processLine line = "<" ++ line ++ ">"
    
    0 讨论(0)
提交回复
热议问题