3

I have the code:

read :: IO [Line]
read = do
  line <- getLine
  let count = length line
  line2 <- getLine 
  if (length line2 /= count) 
  then error "too long or too short"
  else read

What I want to do is, based on the length of the first line the user has to input length-1 more lines, also if any of those lines are not the same length as the original line, an error message will be displayed.

Right now my code is just an infinite loop as I can't quite figure out how to input length-1 more lines. Some guidance for this will be appreciated.

Edit: Line is of type String

1
  • The reason your code is an infinite loop is because the only way you allow it to stop is with the error. Otherwise it will always follow the other branch of the if statement and recurse again and again. Commented Mar 12, 2012 at 18:23

1 Answer 1

5

You can use replicateM to replicate an action a set number of times and collect the results. In your case that action is to grab a line, test its length, and error if it's invalid. So you can use something like the following to accomplish your job:

import Control.Monad (replicateM)

read :: IO [Line]
read = do
  line <- getLine
  let count = length line
  lines <- replicateM (count-1) $ do
    line <- getLine
    if length line /= count
    then fail "too long or too short"
    else return line
  return $ line : lines
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! ReplicateM looks nice although it doesn't seem to stop when necessary (it's going over the count-1 limit!)
replicateM works perfectly, if there is a problem, it's probably in the rest of your code. This is the reasonable position to adopt when a standard piece of simple code seems to fail entirely its purpose : not blaming the standard function and seeking the error in your own code. If you still can't find your error, show your code to some experienced Haskeller, here or on #haskell. If they still can't find an error, it's time to start doubting the standard library.
I guess, just the above code looks fine to me, I'll carry on tweaking it to see if I can find a fix... thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.