Jeffrey
Jeffrey

Reputation: 13

Haskell - keep adding user input ints until a negative is encountered

I'm trying to create a program in Haskell that takes in user inputs, adds each input line up, and spits out the final sum once the user inputs a negative number (the total sum not including the negative number, to be specific). I attempt

    sumF1 :: IO ()
    sumF1 = do
        totSum <- sumF2 0
        print totSum

    sumF2 :: Int -> IO Int
    sumF2 prev = do 
        n<-getInt
        if n<0
            then return prev
            else sumF2 (prev+n)

However, when I try this, I just get a function that prints on every single line and always repeats the input as opposed to summing it up. How do I fix it so that it only prints a sum at the end and that it adds properly.

Upvotes: 0

Views: 802

Answers (4)

eliasmacielr
eliasmacielr

Reputation: 26

The definitions for the functions sumF1 and sumF2 seem to work well, probably the issue is with the getInt function you use to get n each time.

Try adding this line for the definition of getInt:

getInt = getLine >>= \n -> return (read n :: Int)

Which uses getLine from the prelude.

Upvotes: 0

user3125280
user3125280

Reputation: 2829

I don't think it is broken, but I don't know your definition of getInt. For me this one works fine:

getInt :: IO Int
getInt = do str <- getLine
        return (read str)

taken from here.

Upvotes: 0

effectfully
effectfully

Reputation: 12715

I'm trying to create a program in Haskell that takes in user inputs, adds each input line up, and spits out the final sum once the user inputs a negative number

If this is the only thing you want, then you can simply write

main = getContents >>= print . sum . takeWhile (>= 0) . map read . lines

Otherwise you can use this combinator

repeatWhile :: Monad m => (a -> Bool) -> m a -> m [a]
repeatWhile p a = do
    x <- a
    if p x
        then (x:) <$> repeatWhile p a
        else return []

like this

main = repeatWhile (>= 0) readLn >>= print . sum

Upvotes: 3

Paul Johnson
Paul Johnson

Reputation: 17786

Try writing a function which gets the next number and returns a "IO (Maybe Integer)" with "Just" for a positive input and "Nothing" for a negative one. Then use that in a recursive function to create a list of integers (hint: one of its arguments will be the list of integers so far). Then use that in a function that adds up all the integers in the list.

Upvotes: 0

Related Questions