2012-11-03 52 views
1

我是新來的haskell球員。我正在嘗試編寫一個gcd可執行文件。無法與實際類型`[a0]'匹配的預期類型`IO b0'

ghc --make gcd 

當我編譯此代碼時出現以下錯誤。

Couldn't match expected type `IO b0' with actual type `[a0]' 
In a stmt of a 'do' block: 
    putStrLn "GCD is: " ++ gcd' num1 num2 ++ "TADA...." 
In the expression: 
    do { putStrLn "Hello,World. This is coming from Haskell"; 
     putStrLn "This is the GCD"; 
     putStrLn "Frist Number"; 
     input <- getLine; 
     .... } 
In an equation for `main': 
    main 
     = do { putStrLn "Hello,World. This is coming from Haskell"; 
      putStrLn "This is the GCD"; 
      putStrLn "Frist Number"; 
      .... } 

我不明白我的問題在哪裏...這是我的代碼。

gcd' :: (Integral a) => a -> a -> a 
gcd' x y = gcd' (abs x) (abs y) 
     where gcd' a 0 = a 
     gcd' a b = gcd' b (a `rem` b) 

main = do 
    putStrLn "Hello,World. This is coming from Haskell" 
    putStrLn "This is the GCD" 
    putStrLn "Frist Number" 
    input <- getLine 
    let num1 = (read input) 
    putStrLn "Second Number" 
    input2 <- getLine 
    let num2 = read input2 
    putStrLn "GCD is: " ++ gcd' num1 num2 ++ "TADA...." 

我所知道的是,read幫助我將我的字符串轉換爲int。

回答

10

首先,你需要括號,

putStrLn ("GCD is: " ++ gcd' num1 num2 ++ "TADA....") 

或綴功能應用($)

putStrLn $ "GCD is: " ++ gcd' num1 num2 ++ "TADA...." 

不這樣做,該行被解析爲

(putStrLn "GCD is: ") ++ gcd' num1 num2 ++ "TADA...." 

和的級聯IO-action putStrLn "GCD is: "String是什麼導致 - 有點神祕,在有足夠的經驗之前 - 類型錯誤。

從上下文出現 - 在IO -do-block中 - 對於某些b,它必須具有類型IO b。但是從(++)的應用推斷的類型是[a]對於某些類型a。這些類型無法匹配,這就是編譯器報告的內容。

注意,固定在此之後,你還需要將結果轉換的gcd'String

putStrLn $ "GCD is: " ++ show (gcd' num1 num2) ++ "TADA...." 

,否則你會看到另一種類型的錯誤。


從評論

爲了讓我的程序看起來更好。有沒有一種方法可以使輸入區域靠近聲明而不是一條線?

一般來說,是的。而不是使用putStrLn將換行符附加到輸出字符串,而使用putStr,而不是。

putStr "Second Number: " 
input2 <- getLine 

在交互模式(ghci)中,效果很好。 stdout沒有在那裏緩衝。對於已編譯的程序,stdout通常是行緩衝的,這意味着它不會輸出任何內容,直到輸出換行符或緩衝區已滿。

所以對於一個編譯的程序,你需要明確刷新輸出緩衝區,

import System.IO -- for hFlush 

putStr "Second Number: " 
hFlush stdout 
input2 <- getLine 

或關閉緩衝共

import System.IO 

main = do 
    hSetBuffering stdout NoBuffering 
    ... 

但至少曾經在Windows上無法工作的後一種方法(我不確定這是否是固定的,我也不確定hFlush ing是否適用於Windows)。

+0

你是一個天才!謝謝!! – user805981

+0

使我的程序看起來更好。有沒有一種方法可以使輸入區域靠近聲明而不是一條線? – user805981

+1

當然(通常),我會將它添加到答案中,因爲有一點可能不適合評論的緩衝。 –

相關問題