我是哈斯克尔家伙的新手。我正在尝试编写一个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。
答案 0 :(得分:10)
首先,你需要括号,
putStrLn ("GCD is: " ++ gcd' num1 num2 ++ "TADA....")
或中缀函数应用程序($)
:
putStrLn $ "GCD is: " ++ gcd' num1 num2 ++ "TADA...."
没有它,该行被解析为
(putStrLn "GCD is: ") ++ gcd' num1 num2 ++ "TADA...."
并且IO动作putStrLn "GCD is: "
与String
的串联导致 - 在有足够经验之前 - 有点神秘 - 类型错误。
从该行显示的上下文中 - 在IO
- 阻止 - 中,对于某些IO b
,它必须具有b
类型。但是(++)
的应用推断的类型对于某些类型[a]
是a
。这些类型无法匹配,这就是编译器报告的内容。
请注意,修复后,您还需要将gcd'
的结果转换为String
,
putStrLn $ "GCD is: " ++ show (gcd' num1 num2) ++ "TADA...."
或者你会看到另一个类型错误。
来自评论
让我的程序看起来更好。有没有一种方法可以将输入区域放在语句旁边而不是放下行?
总的来说,是的。不使用向输出字符串附加换行符的putStrLn
,而是使用putStr
而不是。{/ p>
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上运行。