Опаловый запрос от String to Maybe
Я хочу выполнить запрос к моей таблице для заданного значения и вернуть Maybe a
в зависимости от того, была ли найдена строка.
У меня есть этот домен:
data User' a b c d e f = User { usrId :: a,
usrApproved :: b,
usrIden :: c,
usrImgUrl :: d,
usrTitle :: e,
usrUrl :: f
}
type User = User' Int Bool String String String String
$(makeAdaptorAndInstance "pUser" ''User')
type UserColumn = User' (Column PGInt4) (Column PGBool) (Column PGText) (Column PGText) (Column PGText) (Column PGText)
и следующие определения для таблицы и запросов:
userTable :: Table UserColumn UserColumn
userTable = Table "user" (pUser User { usrId = required "id",
usrApproved = required "approved",
usrIden = required "identifier",
usrImgUrl = required "img_url",
usrTitle = required "title",
usrUrl = required "url"
})
userQuery :: Query UserColumn
userQuery = queryTable userTable
Как указывалось ранее, я хочу сделать запрос по столбцу "идентификатора", поэтому я написал этот запрос и хочу вернуть `IO (может быть, пользователь)
userByIdenQuery :: (Column PGText) -> Query UserColumn
userByIdenQuery iden = proc () -> do
user <- userQuery -< ()
restrict -< (adIden user) .=== iden
returnA -< user
getUserByIden :: String -> PGS.Connection -> IO (Maybe User)
getUserByIden iden c = do
usr <- runQuery c (userByIdenQuery $ pgString iden)
-- But this fails to compile
undefined -- just to minimise compilation errors
это не компилируется с:
No instance for (Default
Opaleye.Internal.RunQuery.QueryRunner UserColumn haskells0)
arising from a use of `runQuery'
The type variable `haskells0' is ambiguous
Note: there is a potential instance available:
instance (product-profunctors-0.7.1.0:Data.Profunctor.Product.Class.ProductProfunctor
p,
Default p a1_0 a1_1, Default p a2_0 a2_1, Default p a3_0 a3_1,
Default p a4_0 a4_1, Default p a5_0 a5_1, Default p a6_0 a6_1) =>
Default
p
(User' a1_0 a2_0 a3_0 a4_0 a5_0 a6_0)
(User' a1_1 a2_1 a3_1 a4_1 a5_1 a6_1)
-- Defined at src\DB.hs:33:3
In a stmt of a 'do' block:
usr <- runQuery c (userByIdenQuery $ pgString iden)
In the expression:
do { usr <- runQuery c (userByIdenQuery $ pgString iden);
undefined }
In an equation for `getUserByIden':
getUserByIden iden c
= do { usr <- runQuery c (userByIdenQuery $ pgString iden);
undefined }
Если я попытаюсь реализовать функцию:
getUserByIden :: String -> PGS.Connection -> IO (Maybe User)
getUserByIden iden c = do
(usrId, appr, idn, imUrl, tit, url) <- runQuery c (userByIdenQuery $ pgString iden)
return $ Just $ User usrId appr idn imUrl tit url
Затем я получаю эту ошибку компиляции:
Couldn't match expected type `[haskells0]'
with actual type `(Int, Bool, String, String, String, String)'
In the pattern: (usrId, appr, idn, imUrl, tit, url)
In a stmt of a 'do' block:
(usrId, appr, idn, imUrl, tit, url) <- runQuery
c (userByIdenQuery $ pgString iden)
In the expression:
do { (usrId, appr, idn, imUrl, tit, url) <- runQuery
c (userByIdenQuery $ pgString iden);
return $ Just $ User usrId appr idn imUrl tit url }
I really have no idea where to go with this, other than using a library other than Opaleye.
2 ответа
Я не знаком с OpalEye, но я думаю, что вам может понадобиться разумное использование listToMaybe
(import Data.Maybe (listToMaybe)
)
getUserByIden :: String -> PGS.Connection -> IO (Maybe User)
getUserByIden iden c = do
listToMaybe <$> runQuery c (userByIdenQuery $ pgString iden)
Я думаю, что проблема заключается в том, что вы используете undefined
в конце вашей функции getUserByIden
, Из-за некоторого сложного уровня магии, который Opaleye делает под капотом, вам нужно указать тип для использования runQuery
или просто вернуть полученное значение вместо undefined, потому что undefined немного отбрасывает алгоритм верхнего вывода:
getUserByIden :: String -> PGS.Connection -> IO (Maybe User)
getUserByIden iden c = listToMaybe <$> runQuery c (userByIdenQuery $ pgString iden)
Я также добавил listToMaybe
вызов, чтобы изменить тип тела функции в соответствии с указанным вами типом возвращаемого значения. runQuery
при полном применении возвращает значение типа IO [SomeHaskellType]
не IO (Maybe SomeHaskellType)
,