0

I need to get the average, so input is stopped until user puts in a negative number and then the output is the average

  {
    getFloat :: IO Float
    getFloat = do line <- getLine
                    return (read line:: Float) 


    average :: IO Float
    average =  helper summ n
                    where
                    helper :: Float->Float->IO Float
                    helper summ n = do val<-getFloat
                                       if (val<0)
                                          then (return average)
                                          else ( do summ = summ + val
                                                    n = n+1
                                                    average= summ/n
                                                    average)
                                                         }
4
  • 3
    Please paste the error. Also, any question usually should contain at least one ? Commented Feb 21, 2013 at 19:17
  • hs:46:54: parse error on input '=' Commented Feb 21, 2013 at 19:25
  • how do i fix this parse error, and alogotihm to get the correct program Commented Feb 21, 2013 at 19:26
  • Your indentation in getFloat is broken. Is it the same in your file? Commented Feb 21, 2013 at 21:35

2 Answers 2

2

It's better to separate pure and impure computations. I.e., average could be just [a] -> b without IO effects.

main = print =<< average `fmap` go []
  where
    go :: [Int] -> IO [Int]
    go xs = do
      x <- (read :: String -> Int) `fmap` getLine
      if x < 0 then return (x : xs) else go (x : xs)

    average :: [Int] -> Float
    average xs = (fromIntegral $ sum xs) / (fromIntegral $ length xs)

This is not the best solution, by the way:

Sign up to request clarification or add additional context in comments.

Comments

0

Try something like this:

main = do (s,n) <- getnums
          putStrLn $ show $ s / (fromIntegral n)

getnums :: IO (Float, Int)
getnums = go 0.0 0
  where go s n = do line <- getLine
                    let f = read line :: Float
                    if f < 0 then return (s,n)
                             else go (s+f) (n+1)

2 Comments

getLine >>= \line -> return $ read line is the same as read <$> getLine which is the same as readLn. And you don't need an explicit type signature for read if you do something with the result that fixes its type.
True. I think the OP's real problem was how to perform looping in a monadic computation, so I tried to make my code as similar to the original.

Your Answer

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