LINUX.ORG.RU

Вопрос новичка по Haskell


0

0

Выполняю упражнение 3.10 из YAHT.
Нужно написать программу, которая сначала запрашивает числа(до ввода
0), после чего выводит их сумму, произведение и факториал каждого из 
них.
В итоге должно получиться что-то вроде:

Give me a number (or 0 to stop):
5
Give me a number (or 0 to stop):
8
Give me a number (or 0 to stop):
2
Give me a number (or 0 to stop):
0
The sum is 15
The product is 80
5 factorial is 120
8 factorial is 40320
2 factorial is 2

Столкнулся с проблемой перевода чисел сумм, произведений и 
факториалов в строки для вывода посредством putStrLn(т. е. putStrLn 
"The ... is " ++ number) Проблему решил с помощью функции print.
Но на выходе получаеться:

Give me a number (or 0 to stop):
5
Give me a number (or 0 to stop):
8
Give me a number (or 0 to stop):
2
Give me a number (or 0 to stop):
0
The sum is 
15
The product is 
80
5
 factorial is 
120
8
 factorial is 
40320
2
 factorial is 
2
[]
Кто-нибудь может обьяснить, как избавиться от лишних переносов строк 
и правильно завершать работу рекурсивной функции(тут return [] 
использовалось ввиду обязательности else в конструкции if..then..else)

Текст программы:
module Main
    where

      import IO

      askForNumbers = do
        putStrLn "Give me a number (or 0 to stop):"
        number <- getLine
        let num = read(number)
        if num == 0
          then return []
          else do
              rest <- askForNumbers
              return (num : rest)

      fact 1 = 1
      fact a = fact(a-1)*a

      factorial a = do
        if a /= []
          then do
             print( head(a) )
             putStrLn " factorial is "
             print( fact( head( a ) ) )
             factorial( tail a )
          else
             return []

      main = do
        list <- askForNumbers
        putStrLn "The sum is "
        print( foldl (+) 0 list )
        putStrLn "The product is "                 
        print( foldl (*) 1 list )
        factorial list
anonymous

module Main
    where

      import IO

      askForNumbers = do
        putStrLn "Give me a number (or 0 to stop):"
        number <- getLine
        let num = read(number)
        if num == 0
          then return []
          else do
              rest <- askForNumbers
              return (num : rest)

      fact 1 = 1
      fact a = fact(a-1)*a

      factorial a = do
        if a /= []
          then do
             putStrLn $show (head a) ++ " factorial is " ++ show (fact( head( a ) ) )
             factorial( tail a )
          else
             return []

      main = do
        list <- askForNumbers
        putStrLn $ "The sum is " ++ show ( foldl (+) 0 list )
        putStrLn $ "The product is " ++ show ( foldl (*) 1 list )
        factorial list

Pi ★★★★★
()
Ответ на: комментарий от Pi

наверное, надо пояснить: show делает из чего угодно строку - читай дальше про классы, $anything аналогично (anything)

Pi ★★★★★
()
Ответ на: комментарий от Pi

ИМХО factorial лучше переписать так

factorial = mapM_ (\x -> putStrLn $ show x ++ " factorial is " ++ show (fact x))


ну или с явной рекурсией

factorial [] = return ()
factorial (x:xs) = do putStrLn $ show x ++ " factorial is " ++ show (fact x)
                      factorial xs

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.