2
votes

I'm trying to make a really simple twitter client with haskell , and to make things simple i was trying to make a simple putStrLn and getLine (i dont know if this is the best solution for the problem or not, i'm fairly new to haskell).

I wanted to do something like this but the output types are different so its gonna give a massive error :

main:: IO ()
main = do
  putStrLn "1)Tweet\n 2)Timeline\n 3)DM\n 4)Inbox\n"
  numero <- getLine 
  if(numero == 1 ) 
      then do  
          frase <- getLine
          tweet frase 
      else
          if(numero == 2)
              then do 
                  frase <- getLine
                  timeline frase
          else 
              if(numero == 3)
                  then do
                        frase <- getLine 
                        nome <- getLine
                        dm frase nome
                  else 
                     if(numero == 4)
                            then
                                 inbox
                            else do 
                                  PutstrLn "Invalido"


tweet :: String -> IO (Either String Tweet)

timeline :: String  -> IO (Either String [Tweet]) 

dm :: String -> String -> IO(Either String DM)

inbox :: IO(Either String [DM])

And like i explained above its gonna give you errors like :

  Main.hs:86:25: error:
   Couldn't match type ‘Either String DM’ with ‘()’
    Expected type: IO ()
      Actual type: IO (Either String DM)

and :

Main.hs:75:11: error:
• Couldn't match type ‘Either String Tweet’ with ‘()’
  Expected type: IO ()
    Actual type: IO (Either String Tweet)

If someone has an ideia out to solve this particular problem it would be very appreciated .

1
Please post all the relevant code and error messages. It's hard to help you if your post does not provide a Minimal, Complete and Verifiable Example. - Mephy
@Mephy added some examples - user6540722
There's a typo in the question. PutstLn should be putStrLn. - Cirdec

1 Answers

1
votes

If your IO action returns a value, like inbox :: IO(Either String [DM]), but you want to use it where it needs to be an IO () you can ignore the returned value and follow it with a return () which has the type IO ().

  if(numero == 1 ) 
      then do  
          frase <- getLine
          tweet frase 
          return ()
      else
          ...

Aside: you can simplify the indentation for this by using a case expression instead of nested if ... then ... elses.

main:: IO ()
main = do
  putStrLn "1)Tweet\n 2)Timeline\n 3)DM\n 4)Inbox\n"
  numero <- readLn
  case numero of
      1 -> do  
          frase <- getLine
          tweet frase 
          return ()
      2 -> do 
          frase <- getLine
          timeline frase
          return ()
      3 -> do
          frase <- getLine 
          nome <- getLine
          dm frase nome
          return ()
      4 -> do
          inbox
          return ()
      otherwise -> do
          putStrLn "Invalido"

I've also replaced getLine :: IO String with readLn :: Read a => IO a.