2013-02-19 2 views
2

Это то, что у меня есть, я хочу, выход как этотHaskell Некорректное IO выходной

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 6 
(1,2,3) 

Я же продолжать получать без Сумм

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 
(1,2,3) 

**summ :: Integer -> Integer -> Integer -> IO Integer 
summ x1 x2 x3 = return(x1+x2+x3) 
sumThree :: IO (Integer, Integer, Integer) 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       summ x1 x2 x3 
       return(x1,x2,x3)** 

ответ

2

Вы должны на самом деле распечатать результат summ.

Не используйте return в своей функции summ, так что тип результата функции равен Integer, а не IO Integer. Затем,

putStr (show (summ x1 x2 x3)) 

вместо summ x1 x2 x3.

Кроме того, вы знаете о функции sum встроенной (прелюдии) вправо? Он принимает массив Num, поэтому вы можете просто сделать putStr (show (sum [x1, x2, x3])).

+0

вы разрешается иметь только один возврат в функции? – 2013-02-19 02:20:36

+1

Нет, у вас может быть более одного возврата. В Haskell 'return' - это просто функция, которая имеет подпись' a -> M a' для некоторой монады M. В этом случае вы находитесь в монаде 'IO', поэтому' return' имеет тип 'a - > IO a'. Вы должны прочитать о Monads и о том, как они работают в Haskell. Короче говоря, 'return' в Haskell (и в терминологии монадов) - это просто функция преобразования простого значения в монадическое значение и полностью не связана с понятием« return statement »на императивных языках. – tom

+0

пример http://codepad.org/GIuCUlBc –

1

Возможно, я немного читаю ваш код, поэтому, пожалуйста, поправьте меня, если я ошибаюсь, но похоже, что вы смущены тем, как работают программы Haskell, и в частности о том, что означает return.

return в Haskell не является оператором возврата, с которым вы, возможно, знакомы многие языки императивного программирования. return в Haskell - это функция . Как и любая другая функция, вы применяете ее к аргументу для вычисления значения. Он не имеет никакого эффекта на управлении потоком, и, в частности, он не вызывает его аргумент, который будет «возвращен» в качестве значения, вычисленного с помощью функции вы находитесь.

Для IO монады, return является функцией этот тип: return :: a -> IO a, что означает, что он принимает значение в любом типе и дает вам значение в «IO версии этого типа». В частном случае return он дает вам IO-вычисление do-nothing, которое будет производить это значение.

Это:

summ :: Integer -> Integer -> Integer -> IO Integer 
summ x1 x2 x3 = return(x1+x2+x3) 

является очень нечетной функцией для программиста Haskell. Нет необходимости делать IO для вычисления суммы из 3 целых чисел, поэтому почему тип результата IO Integer? Он выглядит мне, как вы пытались написать это:

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = return(x1+x2+x3) 

, который дал бы вам ошибку типа о Integer не будучи монадическим типом. Вы можете исправить это, изменив тип, но тип был правильным выражением суммирования 3 целых чисел, поэтому изменение этого на что-то еще довольно странно. Поскольку return это вовсе не обязательно, чтобы компьютер результат функции, вы можете просто сделать это вместо:

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1+x2+x3 

Аналогично, ваша sumThree функция очень странно.Когда вы делаете это в интерпретатор Haskell:

*Main> sumThree 
Please enter three integers: 
1 
2 
3 
Their sum is: 
(1,2,3) 

Интерпретатор оценивает действия sumThree IO, который просит вас ввести 3 целых числа и печатает «Их сумма:», и выдает значение (1, 2, 3). Действие sumThree ничего не печатает после "Their sum is:", это интерпретатор, который печатает это для вас, и он печатает значение, полученное путем выполнения sumThree.

Это последняя вещь в блоке do, которая определяет значение, полученное sumThree; в этом случае это return(x1,x2,x3). Таким образом, вы можете видеть, что не может быть суммы трех чисел, так как вы явно явно берете кортеж (x1, x2, x3), завершая его в действие IO с return, а затем это результат.

Ваша вторая последняя строка:

summ x1 x2 x3 

находитесь в IO действие (благодаря типу Integer -> Integer -> Integer -> IO Integer для summ). Таким образом, это разрешено сидеть там, и оно «исполнено», чтобы произвести его ценность, но вы ничего с этим не делаете!

Так две вещи:

  1. summ не нужно return вообще
  2. sumThree должны фактически напечатать то, что вы хотите, чтобы напечатать

Полагая, что вместе вы могли бы получить что-то вроде этого :

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1 + x2 + x3 

sumThree :: IO() 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       putStr (show (summ x1 x2 x3)) 

Вот если вы не хотите sumThree, чтобы произвести сумму, а также распечатать ее. Если sumThreeдолжен производить значение, а также печатью, вы хотите что-то больше, как это:

summ :: Integer -> Integer -> Integer -> Integer 
summ x1 x2 x3 = x1 + x2 + x3 

sumThree :: IO Integer 
sumThree = do putStr "Please enter tree integers:" 
       x1 <- getInteger 
       x2 <- getInteger 
       x3 <- getInteger 
       putStr "Their Sum is: " 
       putStr (show (summ x1 x2 x3)) 
       return (summ x1 x2 x3)