Haskell Esqueleto 3 стол соединение - PullRequest
0 голосов
/ 25 октября 2018

Это мои попытки сделать SELECT из трех таблиц.Но они не компилируются, и я не понимаю ошибку (я не знаю, почему она ожидает кортеж (Entity Issue, b0) вместо триплета, который, я думаю, пытается получить код).

Попытка 1:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Handler.Support where

import           Import hiding ((==.))
import qualified Database.Esqueleto as E
import           Database.Esqueleto      ((^.), (==.), (&&.))
import           Data.Traversable

getSupportR :: CustomerId -> Handler Html
getSupportR customerId = do
  customer_issues_followUps_list <- runDB $
    E.select $
    E.from $ \(i, f, c) -> do
    E.where_ (i ^. IssueCustomerId ==. E.val customerId &&. i ^. IssueId ==. f ^. FollowUpIssueId &&. i ^. IssueCustomerId ==. c ^. CustomerId)
    return (i, f, c)
  let issues = map listToMaybe . group . sort . fst . unzip $ customer_issues_followUps_list
  defaultLayout $ do
    setTitle "Your Licenses"
    $(widgetFile "support-display")

ошибка 1:

/home/hhefesto/dev/laurus-nobilis/src/Handler/Support.hs:41:5: error:
    • Couldn't match type ‘(ra, rb, rc)’ with ‘(Entity Issue, b0)’
        arising from a functional dependency between:
          constraint ‘Database.Esqueleto.Internal.Sql.SqlSelect
                        (E.SqlExpr (Entity Issue), E.SqlExpr (Entity FollowUp),
                         E.SqlExpr (Entity Customer))
                        (Entity Issue, b0)’
            arising from a use of ‘E.select’
          instance ‘Database.Esqueleto.Internal.Sql.SqlSelect
                      (a3, b3, c) (ra3, rb3, rc3)’
            at <no location info>
    • In the second argument of ‘($)’, namely
        ‘E.select
           $ E.from
               $ \ (i, f, c)
                   -> do E.where_
                           (i ^. IssueCustomerId ==. E.val customerId
                              &&.
                                i ^. IssueId ==. f ^. FollowUpIssueId
                                  &&. i ^. IssueCustomerId ==. c ^. CustomerId)
                         return (i, f, c)’
      In a stmt of a 'do' block:
        customer_issues_followUps_list <- runDB
                                            $ E.select
                                                $ E.from
                                                    $ \ (i, f, c)
                                                        -> do E.where_
                                                                (i ^. IssueCustomerId
                                                                   ==. E.val customerId
                                                                   &&.
                                                                     i ^. IssueId
                                                                       ==. f ^. FollowUpIssueId
                                                                       &&.
                                                                         i ^. IssueCustomerId
                                                                           ==. c ^. CustomerId)
                                                              return (i, f, c)
      In the expression:
        do customer_issues_followUps_list <- runDB
                                               $ E.select $ E.from $ \ (i, f, c) -> do ...
           let issues
                 = map listToMaybe . group . sort . fst . unzip
                     $ customer_issues_followUps_list
           defaultLayout
             $ do setTitle "Your Licenses"
                  (do ...)
   |
41 |     E.select $
   |     ^^^^^^^^^^...

Попытка 2:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Handler.Support where

import           Import hiding ((==.))
import qualified Database.Esqueleto as E
import           Database.Esqueleto      ((^.), (==.), (&&.))
import           Data.Traversable

getSupportR :: CustomerId -> Handler Html
getSupportR customerId = do
  customer_issues_followUps_list <- runDB $
    E.select $
    E.from $ \(i `E.InnerJoin` f `E.InnerJoin` c) -> do
    E.on (c ^. CustomerId ==. i ^. IssueCustomerId)
    E.on (i ^. IssueId ==. f ^. FollowUpIssueId)
    E.where_ (i ^. IssueCustomerId ==. E.val customerId)
    return (i, f, c)
  let issues = map listToMaybe . group . sort . fst . unzip $ customer_issues_followUps_list
  defaultLayout $ do
    setTitle "Your Licenses"
    $(widgetFile "support-display")

Ошибка 2:

/home/hhefesto/dev/laurus-nobilis/src/Handler/Support.hs:40:5: error:
    • Couldn't match type ‘(ra, rb, rc)’ with ‘(Entity Issue, b0)’
        arising from a functional dependency between:
          constraint ‘Database.Esqueleto.Internal.Sql.SqlSelect
                        (E.SqlExpr (Entity Issue), E.SqlExpr (Entity FollowUp),
                         E.SqlExpr (Entity Customer))
                        (Entity Issue, b0)’
            arising from a use of ‘E.select’
          instance ‘Database.Esqueleto.Internal.Sql.SqlSelect
                      (a2, b2, c) (ra2, rb2, rc2)’
            at <no location info>
    • In the second argument of ‘($)’, namely
        ‘E.select
           $ E.from
               $ \ (i `E.InnerJoin` f `E.InnerJoin` c)
                   -> do E.on (c ^. CustomerId ==. i ^. IssueCustomerId)
                         E.on (i ^. IssueId ==. f ^. FollowUpIssueId)
                         ....’
      In a stmt of a 'do' block:
        customer_issues_followUps_list <- runDB
                                            $ E.select
                                                $ E.from
                                                    $ \ (i `E.InnerJoin` f `E.InnerJoin` c)
                                                        -> do E.on
                                                                (c ^. CustomerId
                                                                   ==. i ^. IssueCustomerId)
                                                              E.on
                                                                (i ^. IssueId
                                                                   ==. f ^. FollowUpIssueId)
                                                              ....
      In the expression:
        do customer_issues_followUps_list <- runDB
                                               $ E.select
                                                   $ E.from
                                                       $ \ (i `E.InnerJoin` f `E.InnerJoin` c)
                                                           -> do ...
           let issues
                 = map listToMaybe . group . sort . fst . unzip
                     $ customer_issues_followUps_list
           defaultLayout
             $ do setTitle "Your Licenses"
                  (do ...)
   |
40 |     E.select $
   |     ^^^^^^^^^^...

это моя постоянная модель:

Customer
    email Text
    password Text
    firstName Text
    lastName Text
    address1 Text
    address2 Text
    city Text
    state Text
    zipCode Text
    country Text
    phone Text
    organization Text
    UniqueCustomer email
    deriving Typeable
    deriving Show
    deriving Eq
    deriving Ord
License
    licenseAlias Text
    expirationDate UTCTime
    assignedTo CustomerId
    customerId CustomerId
    deriving Show
    deriving Eq
    deriving Ord
Issue
    customerId CustomerId
    issueSummary Text
    issueDetails Text
    issueState Int
    issueDate UTCTime
    deriving Show
    deriving Eq
    deriving Ord
FollowUp
    issueId IssueId
    followUpDate UTCTime
    followUpAuthor CustomerId
    followUpText Text
    deriving Show
    deriving Eq
    deriving Ord


-- Soon to be deleted:
Email
    email Text
    customerId CustomerId Maybe
    verkey Text Maybe
    UniqueEmail email
Comment json -- Adding "json" causes ToJSON and FromJSON instances to be derived.
    message Text
    customerId CustomerId Maybe
    deriving Eq
    deriving Show

Как видите, ошибка в обеих попытках одинакова: ожидался кортеж вместо триплета.

Любая помощь будет принята с благодарностью:)

1 Ответ

0 голосов
/ 25 октября 2018

Виновные были в выражении let:

let issues = map listToMaybe . group . sort . fst . unzip $ customer_issues_followUps_list

fst и unzip работают с кортежами, поэтому компилятор подразумевал, что customer_issues_followUps_list был кортежем.

Чтобы решить эту проблему, просто добавьте «-extra» в ваши зависимости package.yml (или ваш файл cabal) и замените fst и unzip на fst3 и unzip3 в операторе let следующим образом:

let issues = map listToMaybe . group . sort . fst3 . unzip3 $ customer_issues_followUps_list
...