What does the Haskell keyword do?

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?

+5
4

   ?

do . , main main = print (isEven 2) print (isOdd 2), , print .

, , , . , Haskell () , .

, print? print - , IO (). IO - , . main , , . , IO . >>, IO.

- "" , "do", - ?

, Monad - ( , : OO), ( ) >> >>=. IO ( : , ), .

do >> >>=. , main do:

main = (print (isEven 2)) >> (print (isOdd 2))

( , , .)

, main IO, print (isEven 2), print (isOdd 2).

+14

, . , do - - . :

main = print (isEven 2) >> print (isOdd 2)

(>>) - . Haskell IO StackOverflow. , , , .

, , , IO - do. .

import System.IO
main = do
  putStr "What your name? "  -- Print strings
  hFlush stdout                -- Flush output
  name <- getLine              -- Get input and save into variable name
  putStrLn ("Hello " ++ name)
  putStr "What your age? "
  hFlush stdout
  age <- getLine
  putStr "In one year you will be "
  print (read age + 1)         -- convert from string to other things with read
                               -- use print to print things that are not strings
+5

Haskell "" , " ": , . , .

IO. : IO Int, IO Char, IO String. IO sometype : " sometype, ".

main IO (). . () - , . main .

IO. >>, , . , , , ( " , " ).

" ", do-notation. - , desugars . , do-notation, ( ) .

+3
source

You know that the result of a function should depend only on its input, so let the model printreflect this:

print :: String -> RealWorld -> (RealWorld, ())

main will look like this:

main rw0 = let (rw1, _) = print (isEven 2) rw0 in
                          print (isOdd 2) rw1

Now let's define bind f g rw = let (rw', ret) = f rw in g rw'which transfers this state RealWorldand rewrites the fragment to use it:

main = bind (print (isEven 2))
            (print (isOdd 2))

Now let's introduce some syntactic sugar that binding does for us

main = do print (isEven 2)
          print (isOdd 2)
0
source

Source: https://habr.com/ru/post/1662079/


All Articles