2

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

*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)**
4

2 回答 2

2

您必须实际打印summ.

不要return在您的summ函数中,以便函数的结果类型IntegerIO Integer. 然后做

putStr (show (summ x1 x2 x3))

而不仅仅是summ x1 x2 x3.

另外,您知道sum内置(Prelude)功能对吗?它需要一个数组Num,所以你可以这样做putStr (show (sum [x1, x2, x3]))

于 2013-02-19T02:03:54.743 回答
1

我可能在这里对您的代码读得过多,所以如果我错了,请纠正我,但看起来您对 Haskell 程序的工作方式感到困惑,尤其是对什么return意思感到困惑。

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

对于IOmonad,return是这种类型的函数:return :: a -> IO a,这意味着它接受任何类型的值并为您提供“该IO类型的版本”中的值。在 的特定情况下return,它为您提供了一个将产生该值的无操作 IO 计算。

这个:

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)

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

这是 do 块中的最后一件事,它决定了sumThree;产生的值。在这种情况下,就是return(x1,x2,x3)。因此,您可以看到这不可能是 3 个数字的总和,因为您非常明确地采用 tuple (x1, x2, x3),将其包装成一个IO带有 的动作return,然后就是结果。

你的倒数第二行:

summ x1 x2 x3

是一个IO动作(感谢Integer -> Integer -> Integer -> IO Integerfor的类型summ)。所以它被允许坐在那里,它被“执行”以产生它的价值,但你对它不做任何事情!

所以有两件事:

  1. summreturn根本不需要
  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)
于 2013-02-19T06:20:57.290 回答