2016-09-03 5 views
0

주어진 값에 대해 내 테이블에 대해 쿼리를 실행하고 행이 있는지 여부에 따라 Maybe a을 반환하고 싶습니다.문자열로 Opaleye 쿼리

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 

나는이 컴파일 오류가되게 해요 : 나는 OpalEye에 익숙하지 않다

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. 
+1

'runQuery'는 매우 일반적인 리턴 타입을 가지고 있습니다 - 타입 시그니처를 주거나 반환 값을 타입 시그니처로 지정하십시오. [docs] (https://hackage.haskell.org/package/opaleye-0.5.0.0/docs/Opaleye-RunQuery.html)는 "runQuery의 Default typeclass 사용은 컴파일러가 유추하는 데 어려움을 겪을 것임을 의미한다 runQuery를 사용할 때 전체 형식 시그너처를 제공하는 것이 좋습니다. " – user2407038

+0

형식 서명을 정확하게 제공하려면 어떻게해야합니까? 방랑자는 항상 거기에서 나를 혼란시켰다. –

+1

어떤 의미에서는'getUserByIden :: String -> PGS.Connection -> IO (Maybe User)'라는 형식 시그니처를 이미 부여했지만'usr'은 본문에서 사용되지 않으므로'User'와 통합 할 수 없습니다. . 함수를 실제로 구현하면 충분할 수 있습니다. 그 동안 당신은'(x :: X) <- a' 또는'x <- a :: IO X' 또는'_x <-a; X :: X; x = _x' – user2407038

답변

3

을하지만, listToMaybe (import Data.Maybe (listToMaybe))

getUserByIden :: String -> PGS.Connection -> IO (Maybe User) 
getUserByIden iden c = do 
    listToMaybe <$> runQuery c (userByIdenQuery $ pgString iden) 
의 적절한 사용이 필요할 수도 있습니다.
1

나는 문제가 getUserByIden의 마지막에 undefined을 사용하여 거짓말한다고 생각한다. Opaleye가 복잡한 유형 수준의 마술을하기 때문에 runQuery을 사용할 유형을 지정하거나 undefined가 대신에 생성 된 값을 반환해야합니다. undefined가 최상위 추론 알고리즘을 약간 끕니다.

getUserByIden :: String -> PGS.Connection -> IO (Maybe User) 
getUserByIden iden c = listToMaybe <$> runQuery c (userByIdenQuery $ pgString iden) 

또한 listToMaybe 호출을 추가하여 함수의 본문 유형을 지정한 반환 유형과 일치하도록 변경했습니다. runQuery은 완전히 적용되면 IO (Maybe SomeHaskellType)이 아닌 IO [SomeHaskellType] 유형의 값을 반환합니다.

+0

고마워요. 다른 답변 (유사한 내용)이 게시되기 전에 귀하의 게시물을 수락했습니다. 도와 줘서 고마워! –