Как я должен был выяснить, что мне не удалось полностью применить функцию из этого сообщения об ошибке ghc?

#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, и в этом случае вы будете применять аргумент впоследствии.

Так что не ленитесь и включите эти подписи типов! 😉