Haskell IO function accepting return value from a another function
module PRO where
average1 :: IO Float
avarage1 =
do
开发者_StackOverflow中文版 putStrLn "Enter Marks in Form of a List"
marks <- getLine
let m = (read marks)::[Int]
x<-(sum' (m))
avg <- x/length (m)
if(x/=[])
then
putStrLn ("empty List")
else
putStrLn ("Your Avarage is " ++ show(avg))
sum' :: (Num a) => [a] -> a
sum' xs = foldl (\acc x -> acc + x) 0 xs
My program doesn't seems to work! My question is why can't I assign avg
the returning sum
of the sum'
function?
module PRO where
average1 :: IO ()
average1 =
do
putStrLn "Enter Marks in Form of a List"
marks <- getLine
let m = (read marks)::[Int]
let x = sum' m
let avg = (fromIntegral x)/(fromIntegral $ length m)
if(m==[])
then
putStrLn ("empty List")
else
putStrLn ("Your Avarage is " ++ (show avg))
sum' :: (Num a) => [a] -> a
sum' xs = foldl (\acc x -> acc + x) 0 xs
i) The type signature of average1
is incorrect, the function does not return a value
ii) [Edit: this point was incorrect]
iii) the average value is a float, so you need to cast the integer arguments
iv) Your test if (x/=[])
is the wrong way round and should use m
not x
v) most of your lines are not in the IO
monad and so should use let
inside a do
block
You can't use the <-
notation for assigning the return values of sum' m
and x/length m
. <-
can only be used when the right-hand side is a monadic expression (in this case, an IO
value), which neither one is, and so you should use let x = sum' m
and let avg = x / fromInteger (length m)
instead (fromInteger
is needed to convert the Int
returned by length m
to a Fractional value so it can be passed to /
). (Also, you need to change x /= []
to m /= []
.)
精彩评论