This will benefit from a key principle: separate your clean code from your IO as much as possible. This will increase your programs and save the main breif. A lot of let in a large main not a very functional approach and tends to become much more messy as your code grows.
Using a type signature and readLn , which essentially fmap read getLine helps reduce some cracks. (If you are new to fmap , visit the question How do functors work in haskell?. fmap really a very flexible tool.)
getInts :: IO (Int, Int) getInts = do putStrLn "Please enter the dividend :" x <- readLn putStrLn " Please enter the divisor :" y <- readLn return (x,y)
Now processing. If I did more with this data or more often, I would use the record type to store dividends, dividers, private and the rest, so keep this in mind for the future, but here is an excess.
I am hackingly returning a list, not a tuple, so I can use map to show everything:
sums :: (Int, Int) -> [Int] sums (x,y) = [x, y, q, r, y * q, y * q + r] where q = x `div` y r = x `mod` y
The final piece of the puzzle is the way out. Again, I prefer to generate this external IO, and then I can just mapM_ putStrLn on it later print each line. I would prefer this to take the record type, but I endure the list of strings as input instead, since I assume that I already have show n everything.
explain :: [String] -> [String] explain [x,y,q,r,yq,yq_r] = [ concat ["Result: ", x, " / ", y, " = ", q, " remainder ", r] , concat ["Proof: (", y, " x ", q, ") + ", r, " = ", yq, " + ", r, " = ", yq_r] , "Is this what you had? "]
Now we can write main as
main = do (x,y) <- getInts let ns = map show ( sums (x,y) ) es = explain ns mapM_ putStrLn es
or even more succinctly by combining explain . map show . sums functions explain . map show . sums explain . map show . sums explain . map show . sums and applying them to the getInts output using fmap :
main :: IO () main = fmap (explain . map show . sums) getInts >>= mapM_ putStrLn
You may have noticed that in the proof I added +r to make = always mean = , which is the correct mathematical use, and displays the Haskell value for =.