#haskell #monads #currying
#haskell #монады #каррирование
Вопрос:
Я получил сообщение об ошибке от ghc, которое я не отменял, и сократил свой код до:
import System.Process
main = do
(_, out, _) <- readProcessWithExitCode "echo" ["foo"]
putStr out
(Я должен был указать дополнительный аргумент для readProcessWithExitCode). Компиляция этой сломанной программы с использованием runghc дает:
Test.hs:4:2:
Couldn't match expected type `IO
(GHC.IO.Exception.ExitCode, String, String)'
against inferred type `(a, b, c)'
In the pattern: (_, out, _)
In a stmt of a 'do' expression:
(_, out, _) <- readProcessWithExitCode "echo" ["foo"]
In the expression:
do { (_, out, _) <- readProcessWithExitCode "echo" ["foo"];
putStr out }
Как я должен был выяснить, что мне не удалось полностью применить функцию из этого сообщения об ошибке ghc?
Комментарии:
1. В следующий раз вы будете знать. То есть ответ — это опыт.
Ответ №1:
Если вы указали сигнатуру типа main :: IO ()
, ошибка становится:
test.hs:5:18:
Couldn't match expected type `IO t0'
with actual type `String
-> IO (GHC.IO.Exception.ExitCode, String, String)'
In the return type of a call of `readProcessWithExitCode'
In a stmt of a 'do' expression:
(_, out, _) <- readProcessWithExitCode "echo" ["foo"]
In the expression:
do { (_, out, _) <- readProcessWithExitCode "echo" ["foo"];
putStr out }
В этом случае ошибка намного более очевидна.
Я предполагаю, что ошибка не так ясна, потому что при выводе типа GHC думает, что вы находитесь в функции (т. Е. (a->)
) monad, а не IO, и в этом случае вы будете применять аргумент впоследствии.
Так что не ленитесь и включите эти подписи типов! 😉