2017-04-25 72 views
1

在下面的代码中,我试图显示factorial(整数)的结果。我收到以下错误消息,我想知道发生了什么以及为什么。谢谢!在if-else语句中无法显示/打印int

factorial2 0 = 1 
factorial2 n = n * factorial2 (n-1) 

main = do putStrLn "What is 5! ?" 
     x <- readLn 
     if x == factorial2 5 
      then putStrLn "Right" 
      -- else print factorial2 5 -- why can't pass here 
      -- else show factorial2 5 -- why can't pass here 
      else putStrLn "Wrong" -- this can pass, no problem 

-- Factorial.hs:10:20: 
--  Couldn't match expected type ‘Integer -> IO()’ 
--     with actual type ‘IO()’ 
--  The function ‘print’ is applied to two arguments, 
--  but its type ‘(a0 -> a0) -> IO()’ has only one 
--  In the expression: print factorial2 5 
--  In a stmt of a 'do' block: 
--  if x == factorial2 5 then putStrLn "Right" else print factorial2 5 
-- Failed, modules loaded: none. 

回答

3

Haskell函数应用程序是关联的。这意味着当你打电话给print factorial2 5时,haskell会解释它,因为你传递了两个参数来打印:factorial25,但打印只需要一个参数。如果你的代码是另一种语言,它将相当于:print(factorial2, 5)

原因show factorial2 5不起作用,因为你的do块中的所有内容都需要返回一个IO(),但是show factorial2 5返回一个字符串。

只需print (factorial2 5)将工作,以便haskell知道您想要将factorial2 5的结果传递给print

+1

我会说Haskell(函数应用程序)是* left * associative:'print factorial2 5'与'(print factorial2)5'相同。 –

+0

@DavidYoung感谢你是完全正确的,让我的左右混合了哈哈。编辑我的帖子。 –

0

功能显示的类型为:a -> String。 所以它需要一个参数并将其转换为一个字符串。

在你行

else show factorial2 5 -- why can't pass here 

你给论点,即factorial2和。

你必须给一个函数参数显示,在你的案件factorial2 5的结果。因此你必须把factorial2 5到括号:

else show (factorial2 5) 

你经常会看到$运营商:

else show $ factorial2 5 

它允许您保存括号。