Функция ввода-вывода Haskell, принимающая возвращаемое значение от другой функции

#haskell #input

#haskell #ввод

Вопрос:

 module PRO where
average1 :: IO Float
avarage1  =
    do
        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
  

Похоже, моя программа не работает! Мой вопрос в том, почему я не могу назначить avg возвращаемое значение sum sum' функции?

Ответ №1:

 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) Сигнатура типа average1 неверна, функция не возвращает значение

ii) [Редактировать: этот пункт был неверным]

iii) среднее значение имеет значение с плавающей точкой, поэтому вам нужно привести целочисленные аргументы

iv) Ваш тест if (x/=[]) выполнен неверно и должен использовать m не x

v) большинство ваших строк не находятся в IO монаде и поэтому должны использоваться let внутри do блока

Комментарии:

1.MacPhail большое спасибо за вашу помощь. Код скомпилирован без проблем, но я все еще получаю сообщение об ошибке во время выполнения PRO> average1 Enter Marks in Form of a List [1,2,3] Your Avarage is Program error: Prelude.read: no parse

2. @jwodder @Vivian McPhail поняла, спасибо за помощь, которую вы, ребята, оказали. ты молодец!

Ответ №2:

Вы не можете использовать <- обозначение для присвоения возвращаемых значений sum' m и x/length m . <- может использоваться только тогда, когда правая часть является монадическим выражением (в данном случае IO значением), которым ни одно из них не является, и поэтому вместо этого вам следует использовать let x = sum' m и let avg = x / fromInteger (length m) ( fromInteger необходимо преобразовать Int возвращаемое length m значение в дробное, чтобы его можно было передать / ). (Кроме того, вам нужно изменить x /= [] на m /= [] .)

Комментарии:

1. спасибо jwodder! но я все еще не могу разрешить вычислить среднее значение, я получаю ошибку ОШИБКА файла:. PRO.hs: ошибка 10 — го типа в приложении *** Выражение: fromInteger (длина m) *** Термин: длина m *** Тип: Int *** Не соответствует: Integer

2. @visuddha используется fromIntegral для принудительного ввода целых типов.