I am a C ++ / Java programmer, and I am trying to learn Haskell (and functional programming in general), and I had a rude solution. One thing I tried was the following:
isEven :: Int -> Bool
isEven x =
if mod x 2 == 0 then True
else False
isOdd :: Int -> Bool
isOdd x =
not (isEven x)
main =
print (isEven 2)
print (isOdd 2)
But this failed with this error at compile time:
ghc --make doubler.hs -o Main
[1 of 1] Compiling Main ( doubler.hs, doubler.o )
doubler.hs:11:5: error:
• Couldn't match expected type ‘(a0 -> IO ()) -> Bool -> t’
with actual type ‘IO ()’
• The function ‘print’ is applied to three arguments,
but its type ‘Bool -> IO ()’ has only one
In the expression: print (isEven 2) print (isOdd 2)
In an equation for ‘main’: main = print (isEven 2) print (isOdd 2)
• Relevant bindings include main :: t (bound at doubler.hs:10:1)
make: *** [all] Error 1
So, I saw the code online with the keyword "do", so I tried it as follows:
isEven :: Int -> Bool
isEven x =
if mod x 2 == 0 then True
else False
isOdd :: Int -> Bool
isOdd x =
not (isEven x)
main = do
print (isEven 2)
print (isOdd 2)
And it worked just like I thought it should be.
What's going on here? Why does the first piece of code not work? And what does “do” really add?
PS. I saw something about the "monads" on the Internet related to the keyword "do", something related to this?