Benjamin Sx
Benjamin Sx

Reputation: 287

Haskell, Create list with user input

Hello I need to create a list from the user input and stop when "END" is detected. I'm learning Haskell so it's a bit confuse with the IO.

I have this code to recursivly add the input in a list and when "END" is write by the user it give the list

getList :: [String] -> IO [String]
getList list =  do line <- getLine
                   if line ==  "END"
                      then return list
                      else getList (line : list)

and I try to catch the result and print it in this function, it already take two parameter that I didn't code already.

checkDebruijn :: Int -> String -> IO ()
checkDebruijn sequence alphabet  = do
    print (getList [])

And I call it in the main to test it

main :: IO ()
main = do
  print (checkDebruijn 0 "")

And I have this error :

No instance for (Show (IO [String]))
        arising from a use of ‘print’
    • In a stmt of a 'do' block: print (getList [])
      In the expression: do print (getList [])
      In an equation for ‘checkDebruijn’:
          checkDebruijn sequence alphabet = do print (getList [])
  |
7 |     print (getList [])
  |     ^^^^^^^^^^^^^^^^^^

I see that print is : print :: Show a => a -> IO () So I don't understand why it wouldn't compile. For me IO is an action that the compiler do. So getList :: [String] -> IO [String] IO [String] is when the compiler do an action and return a [String] ?

Upvotes: 0

Views: 2065

Answers (2)

Mateen Ulhaq
Mateen Ulhaq

Reputation: 27191

Your main should look like:

main = getList [] >>= print

where:

(>>=) :: Monad m => m a -> (a -> m b) -> m b

Or alternatively:

main = do
  xs <- getList []
  print xs

Upvotes: 3

Lee
Lee

Reputation: 144126

As you say, print has type

print :: Show a => a -> IO ()

and getList [] has type IO [String], so for print (getList []) to typecheck there must be a Show instance for IO [String]. There is no such instance, which causes the error.

There is a Show instance for [String] however, so you can call print on the list returned by executing getList []. You can use do notation to bind the result to call print on it:

checkDebruijn sequence alphabet  = do
    result <- (getList [])
    print result

Upvotes: 2

Related Questions