Haskell不正确的IO输出

时间:2013-02-19 01:47:02

标签: design-patterns haskell io return

这就是我所拥有的,我想要一个像这样的输出

*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 个答案:

答案 0 :(得分:2)

您必须实际打印summ的结果。

return函数中不要summ,因此函数的结果类型为Integer而不是IO Integer。然后,做

putStr (show (summ x1 x2 x3))

而非summ x1 x2 x3

另外,您确实知道sum内置(Prelude)功能吗?它需要Num个数组,因此您可以putStr (show (sum [x1, x2, x3]))

答案 1 :(得分:1)

我可能在这里读了太多代码,所以如果我错了请纠正我,但看起来你对Haskell程序的工作原理感到困惑,尤其是return意味着什么

Haskell中的

return不是许多命令式编程语言可能熟悉的返回语句。 Haskell中的return函数。与任何其他函数一样,您将其应用于计算值的参数。它对流控制有无效,特别是它不会导致其参数被“返回”为您所在函数计算的值。

对于IO monad,return是此类型的函数:return :: a -> IO a,这意味着它采用任何类型的值并为您提供“{{1该类型的版本“。在IO的特定情况下,它会为您提供无效的IO计算,从而产生该值。

此:

return
对于Haskell程序员来说,

是一个非常奇怪的函数。没有必要使用IO来计算3个整数的总和,那么为什么结果类型为summ :: Integer -> Integer -> Integer -> IO Integer summ x1 x2 x3 = return(x1+x2+x3) ?它似乎对我来说就像你试图写这个:

IO Integer

这会给你一个关于summ :: Integer -> Integer -> Integer -> Integer summ x1 x2 x3 = return(x1+x2+x3) 不是monadic类型的类型错误。您可以通过更改类型来解决这个问题,但类型是对3个整数求和的正确表达式,因此将其更改为其他内容则相当奇怪。由于Integer根本不需要计算函数的结果,所以你可以这样做:

return

同样,您的summ :: Integer -> Integer -> Integer -> Integer summ x1 x2 x3 = x1+x2+x3 功能非常奇怪。当你在Haskell解释器中执行此操作时:

sumThree

解释器正在评估*Main> sumThree Please enter three integers: 1 2 3 Their sum is: (1,2,3) IO动作,它要求您输入3个整数并打印“它们的总和是:”,并生成值sumThree(1, 2, 3)操作本身不会在sumThree之后打印任何内容,它是为您打印的解释器,并且它正在打印执行"Their sum is:"生成的值。

这是do块中最后一个决定sumThree产生的值的东西;在这种情况下是sumThree。所以你可以看到,没有办法可能是3个数字的总和,因为你非常明确地使用元组return(x1,x2,x3),将其包含在(x1, x2, x3)动作中IO },那就是结果。

你的第二句话:

return

是一项summ x1 x2 x3 操作(感谢IO的{​​{1}}类型。所以它被允许坐在那里,它被“执行”以产生它的价值,但是你没有做任何事情!

所以有两件事:

  1. Integer -> Integer -> Integer -> IO Integer根本不需要summ
  2. summ应该实际打印您要打印的内容
  3. 把它放在一起就可以得到这样的东西:

    return

    如果您不希望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