Понимание ошибки типа функции подключения Haskell postgresql

#postgresql #haskell

#postgresql #haskell

Вопрос:

Сейчас я Java-программист, читающий и изучающий haskell. Я пытаюсь написать простую программу для подключения (и отключения) к базе данных postgres с использованием драйвера HDBC postgres. Для простоты у меня нет никакой другой логики в этом.

Это выдает ошибку типа функции. Я сделал правильный отступ в коде, и если я удалю disconnect, то он будет работать с определенным типом.

Может ли кто-нибудь пролить свет на то, чего мне не хватает, определяя тип для этой функции? я бы отказался от вашей помощи.

Спасибо!

пример кода:

 import Database.HDBC
import Database.HDBC.PostgreSQL
import Database.HaskellDB
import Database.HaskellDB.HDBC.PostgreSQL

tryConnect :: Int  -> (Database -> IO Connection) -> ()   
tryConnect id =
   do
     c <- postgresqlConnect [("host","dbhost"),("dbname","db1"),("user","user1"),("password","test")]
     disconnect c
     return ()
  

Я получаю следующую ошибку от GHCi

    Couldn't match expected type `(Database -> IO Connection) -> a'
       against inferred type `IO ()'
In a stmt of a 'do' expression: disconnect c
In the expression:
    do { c <- postgresqlConnect
                [("host", "dbhost"), ("dbname", "db1"), ....];
         disconnect c;
         return () }
In the definition of `insrt':
    insrt id
            = do { c <- postgresqlConnect [("host", "dbhost"), ....];
                   disconnect c;
                   return () }
  

Сбой, загруженные модули: отсутствуют.

Ответ №1:

Проблема в том, что вы не предоставили достаточно аргументов для postgresqlConnect . Ее сигнатура типа [(String, String)] -> (Database -> m a) -> m a , но вы указали только первый аргумент. Предоставление postgresqlConnect ее второго аргумента должно решить проблему, и вы сможете изменить объявление типа обратно на Int -> IO () .

РЕДАКТИРОВАТЬ: Приведенный ниже ответ абсолютно неверен. Моя ошибка.

Ну, подпись типа является tryConnect :: Int -> (Database -> IO Connection) -> () . Обычно это указывает на то, что функция принимает Int и a (Database -> IO Connection) и возвращает () , но единственным параметром, который вы указали в определении функции, является id . Таким образом, у вас действительно есть функция, которая принимает Int и возвращает новую функцию с сигнатурой типа (Database -> IO Connection) -> () .

Это было бы прекрасно, за исключением того, что тело функции не соответствует этой подписи. do Выражение возвращает IO () значение, а не ожидаемую функцию, поэтому вы получаете ошибку, потому что компилятор получил возвращаемое значение, отличное от ожидаемого.

Итак, в заключение, похоже, что в сигнатуре типа есть параметр, который вы не использовали в реальной функции. Либо удалите эту функцию из подписи типа, либо измените функцию на быть, tryConnect id func = ... а не tryConnect id = ... .

Комментарии:

1. спасибо Джеффри. Тип определяется мной, а не функцией. я не был уверен в этом ранее. Изначально я пробовал с этим типом,

2. Попробуйте подключить :: Int -> IO (). Это приводит к следующему исключению

3. мои плохие .. комментарии нарушены. { Не удалось сопоставить ожидаемый тип IO ()' against inferred type (База данных -> ma) -> b’ В stmt выражения ‘do’: c <- postgresqlConnect [(«хост», «dbhost»), («dbname», «db1»), («пользователь», «user1»), («пароль», «тест»)] В выражении: do { c <- postgresqlConnect [(«хост», » dbhost»), («dbname», «db1»), ….]; отключить c; вернуть () } }

4. В функции, которую вы написали в вопросе, попробуйте изменить () в конце на IO () и посмотрите, компилируется ли это.

5. Я попытался перейти на IO () и все еще получаю ошибку. Он жалуется на функцию отключения. Вот ошибка: {Не удалось сопоставить ожидаемый тип (Database -> IO Connection) -> a' against inferred type IO ()’ В stmt выражения ‘do’: disconnect c }