Не удалось сопоставить ожидаемый тип `IO b0'с фактическим типом`[a0]'
Я новичок в 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.
1 ответ
Во-первых, вам нужны скобки,
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
-do-block - должен иметь тип IO b
для некоторых 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
работает на Windows).