1

Haskellの人は初めてです。gcd実行可能ファイルを書き込もうとしています。

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に変換するのに役立つということだけです。

4

1 に答える 1

10

まず、括弧が必要です、

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

または中置関数適用($)

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

それがないと、行は次のように解析されます

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

そして、IO-actionputStrLn "GCD is: "とaの連結がString、-十分な経験を積む前に-やや不可解な-タイプエラーを引き起こす原因です。

行が表示されるコンテキストから(IO-do-block内) IO b、いくつかのタイプが必要bです。しかし、のアプリケーションから推測されるタイプ(++)[a]、あるタイプのものaです。これらのタイプは一致させることができず、それがコンパイラーが報告するものです。

gcd'これを修正した後、の結果をに変換する必要があることに注意してくださいString

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

または、別のタイプエラーが表示されます。


コメントから

私のプログラムをより見栄えよくするため。入力領域が行下ではなくステートメントのすぐ隣にある方法はありますか?

一般的に、はい。putStrLn出力文字列に改行を追加するwhichを使用する代わりに、putStrそうでないwhichを使用します。

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、Windowsでingが機能することも絶対に確信していません)。

于 2012-11-03T18:31:18.967 に答える