How do I make interact point-free?
Question
shortLinesOnly :: IO ()
shortLinesOnly = interact result
where
shortLength = 11
onlyShorts = (<= shortLength) . length
shortLines = filter onlyShorts . lines
result = unlines . shortLines
interact result = getContents >>= putStr . result
In the above code how can I write the interact function in point free style.
Solution
Step by step:
interact r = getContents >>= putStr . r
interact r = (getContents >>=) (putStr . r)
interact r = (getContents >>=) $ (putStr .) $ r
interact = (getContents >>=) . (putStr .)
OTHER TIPS
The best answer is: Don't. For this particular example the only change that would make is that your code would be less readable. Your original pointy variant is perfectly fine.
In certain cases it is better to avoid pointfree style. This is one of them, because your argument does not undergo linear data flow. It is rather used to build the data flow for something else. Example:
-- Bad: Pointy linear data flow description.
chunksOf :: Int -> [a] -> [[a]]
chunksOf n xs =
takeWhile (not . null) (map (take n) (iterate (drop n) xs))
-- Good: Pointfree linear data flow description.
chunksOf :: Int -> [a] -> [[a]]
chunksOf n =
takeWhile (not . null) . map (take n) . iterate (drop n)
-- Bad: Now exaggerating with pointfree style.
chunksOf :: Int -> [a] -> [[a]]
chunksOf =
liftA2 ((.) (.) . (.) $ takeWhile (not . null))
(map . take)
(iterate . drop)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow