I'm just starting to learn Haskell after first getting my hands dirty in functional programming with python.
First of all, I know what I will ask is bad practice is virtually every programming language known to man, and I promise to not use this in any serious purpose other than purely educational. That said...
One of the things I liked best was the elegance of writing a function using just one line of code while still keeping the code readable(things like C/C++ style where you just place all the statements on one line separated by semicolons don't count, obviously)
I have looked trough questions and tried at least a few different haskell tutorials and documentations and some things have gotten close, but I could not find something that lets me read a usable Int in one line of code.
For the sake of the question let's say I want something like reading an Int for the keyboard and printing "Hello World!" that many times(shamelessly stolen from HackerRank).
The things I have tried using getLine
, readLn
, read
, looked into >>=
instead of do notation, only to remain stuck with IO operations stubbornly giving me an error every time I did not put them in a separate statement.
Some of the things I have tried:
main :: IO ()
main = readLn :: IO Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"
gives:
parse error on input ‘\’
Then
main = readLn >>= \n -> read n :: Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"
Gives the same error.
Same with:
main = getLine >>= \n -> read n :: Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"
What exactly am I not understanding? Thanks in advance!
You're mixing type declarations with expressions. It should be:
main = (readLn :: IO Int) >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"
Your problem was that without bracketing, the compiler continues to parse as if it were reading a type declaration, and so it ran across \
and got stuck.
However, this type declaration is inferred (since replicate :: Int -> a -> [a]
) and thus unnecessary. Remove it!
main = readLn >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"
In general however, it's much better to avoid this entirely and just use do
-notation. This kind of 'golfing' in Haskell is very fun, but not the way to make clear, maintainable code.
import Control.Monad (replicateM_)
main = do
n <- readLn :: IO Int -- Type optional here.
replicateM_ n $ putStrLn "Hello World!" -- A more concise expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With