I'm new to Haskell and i'm now watching the "Haskell Rank" series on youtube and i feel i need a better understanding of what's going on in the first video so i can move on.
He starts with the basic "solve me first" exercise on hackerrank, which already comes with the solution:
solveMeFirst a b = a b
main = do
val1 <- readLn
val2 <- readLn
let sum = solveMeFirst val1 val2
print sum
this is clear, if i put it in a file, compile it and run it, it behaves as expected:
- takes two lines of input
- prints the sum of the numbers from the user input
through several steps of explaining the roles of each function, he reaches a more functional one-line solution;
he gets there by first working up to the following:
> show $ sum $ map read $ words "1 2"
3
Up until here, i understand everything, including the use of the ($) operator.
To finish, he then defines the main function, using interact
to handle the input from stdin
and there are two things i really don't understand:
1 - the function composition: he then reaches the solution of:
main = interact $ show . sum . map read . words
where he grabs the previous build up, removes the input "1 2"
to compose the function that will be the argument for interact
. And, what he doesn't explain thoroughly is "and replace all of its dollar signs with functional composition."
Would love a detailed explanation of step-by-stepping this "inversion" process.
2 - using this one-line solution, and compiling it from a file,
how can i run the file, sending the input as args
?
CodePudding user response:
The conversion to composition is based on the simple definition of the .
operator (shown here using $
to make the link clear).
(.) f g = \x -> f $ g x
show . sum . map read . words
is the same as \x -> show $ sum $ map read $ words x
.
The composed function is never explicitly applied to an argument because interact
takes the function and produces an IO ()
value which, when executed by the runtime, will apply the function to an argument also supplied by the runtime.
The runtime supplies the input by reading from standard input.