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 bsome的类型b。但是从应用中推断出的类型(++)[a]针对某种类型的a。这些类型无法匹配,这就是编译器报告的内容。

请注意,修复后,您还需要将结果转换gcd'为 a String

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

否则你会看到另一个类型错误。


从评论

为了让我的程序看起来更好。有没有办法让输入区域就在语句旁边而不是一行?

一般来说,是的。而不是使用putStrLnwhich 将换行符附加到输出字符串,使用putStrwhich 不。

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 上不起作用(我不确定这是否已修复,我也不确定hFlushing 在 Windows 上是否有效)。

于 2012-11-03T18:31:18.967 回答