#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 }