Home > OS >  Haskell: Getting error when accepting string input in user defined function
Haskell: Getting error when accepting string input in user defined function

Time:09-07

I'm a newbie in Haskell. Was trying a code to take input string in user defined function and further perform tasks as per argument passed to function in main.

main :: IO()
main=do
{
    print(f 2)
}
f::Int->Int
f n=do
{
    inp<-getLine;
    if (inp=="hello") then (n 2);
    else                   (n);
}

Since this function takes int and returns int, I defined it as Int->Int. However I feel something's missing. I'm getting the following error:-

[1 of 1] Compiling Main             ( main.hs, main.o )
main.hs:9:5: error:
    • Couldn't match expected type ‘Int’ with actual type ‘IO b0’
    • In a stmt of a 'do' block: inp <- getLine
      In the expression:
        do inp <- getLine
           if (inp == "hello") then (n   2) else (n)
      In an equation for ‘f’:
          f n
            = do inp <- getLine
                 if (inp == "hello") then (n   2) else (n)
  |
9 |     inp<-getLine;
  |     ^^^^^^^^^^^^
main.hs:10:29: error:
    • Couldn't match expected type ‘IO b0’ with actual type ‘Int’
    • In the expression: (n   2)
      In a stmt of a 'do' block:
        if (inp == "hello") then (n   2) else (n)
      In the expression:
        do inp <- getLine
           if (inp == "hello") then (n   2) else (n)
   |
10 |     if (inp=="hello") then (n 2);
   |                             ^^^
main.hs:11:29: error:
    • Couldn't match expected type ‘IO b0’ with actual type ‘Int’
    • In the expression: (n)
      In a stmt of a 'do' block:
        if (inp == "hello") then (n   2) else (n)
      In the expression:
        do inp <- getLine
           if (inp == "hello") then (n   2) else (n)
   |
11 |     else                   (n);
   |                             ^

How to rectify this error??

CodePudding user response:

A do block almost always indicates that you are defining a monadic computation(1). Therefore the type of f has to be Int -> IO Int (IO is induced by the use of getLine here). Additionally, since the result has to be contained in a monadic context, you should wrap n 2 and n with return.

So the final code of f should be

f :: Int -> IO Int
f n = do
    inp <- getLine
    if inp == "hello" then return (n   2)
    else                   return n

Note that the use of f in main has to be adjusted accordingly.


(1)sometimes applicative, but anyway

  • Related